Compare commits
83 Commits
harmony-v3
...
harmony-v3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b2e6b81a2 | ||
|
|
f9e9898dc1 | ||
|
|
7c0c92943f | ||
|
|
62a66dfff4 | ||
|
|
c44d78db55 | ||
|
|
8c763bf2b5 | ||
|
|
2cab348341 | ||
|
|
aa1786dedf | ||
|
|
0d5df271a1 | ||
|
|
b56e1f178f | ||
|
|
9acace2cb6 | ||
|
|
0f2be1456c | ||
|
|
460218a3f8 | ||
|
|
e49416e4aa | ||
|
|
d4d7d99b70 | ||
|
|
6a696d0a7b | ||
|
|
1c9e13f47d | ||
|
|
b757450cd8 | ||
|
|
23ec484806 | ||
|
|
f1e1bb419a | ||
|
|
6a0af85c8b | ||
|
|
1eb15f46f1 | ||
|
|
09269be974 | ||
|
|
137cb73d1f | ||
|
|
bf832cde16 | ||
|
|
2972d58dbb | ||
|
|
2e22d38a02 | ||
|
|
ce27bcd69a | ||
|
|
1f3f8f25eb | ||
|
|
4b1799ecdd | ||
|
|
7a8eff62ca | ||
|
|
9336cc8247 | ||
|
|
9809567dfc | ||
|
|
1ee8be8d91 | ||
|
|
8430c2f9f8 | ||
|
|
659c8a7632 | ||
|
|
3564b4f20d | ||
|
|
3505a3604a | ||
|
|
9b1bc6c014 | ||
|
|
9f23185f2b | ||
|
|
b82feb9302 | ||
|
|
7f2a591c7e | ||
|
|
f76b5e0f43 | ||
|
|
afbcebddf6 | ||
|
|
484e484571 | ||
|
|
6f3f21233f | ||
|
|
a6873a3859 | ||
|
|
7a6d452b54 | ||
|
|
9b58b54e2d | ||
|
|
c598a12af9 | ||
|
|
cfe3a98ce5 | ||
|
|
14778e049b | ||
|
|
446fb0198b | ||
|
|
7d3cddf9d6 | ||
|
|
6dead95eb3 | ||
|
|
cc931b3ad8 | ||
|
|
ffc64e2279 | ||
|
|
d838b4b52e | ||
|
|
2f3bddbaca | ||
|
|
673b071637 | ||
|
|
da82fa59a7 | ||
|
|
333792352e | ||
|
|
a6653e2102 | ||
|
|
3bbe839518 | ||
|
|
e2ec270b04 | ||
|
|
ace272f0c5 | ||
|
|
ed7a0a454e | ||
|
|
725aac8b46 | ||
|
|
d819559a01 | ||
|
|
53600e9869 | ||
|
|
7dea749f58 | ||
|
|
8ca49155a8 | ||
|
|
b95e3338d9 | ||
|
|
e40a0ee9c6 | ||
|
|
0a3fac6e68 | ||
|
|
cb62bd98d3 | ||
|
|
9f7d1f7ac6 | ||
|
|
f30790b11b | ||
|
|
5205dbcbf4 | ||
|
|
3ff625de7e | ||
|
|
4832bc5d88 | ||
|
|
7f342cb3e3 | ||
|
|
05e7d34ed4 |
@@ -675,7 +675,13 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
|
|
||||||
- `if_return` (default: `true`) -- optimizations for if/return and if/continue
|
- `if_return` (default: `true`) -- optimizations for if/return and if/continue
|
||||||
|
|
||||||
- `inline` (default: `true`) -- embed simple functions
|
- `inline` (default: `true`) -- inline calls to function with simple/`return` statement:
|
||||||
|
- `false` -- same as `0`
|
||||||
|
- `0` -- disabled inlining
|
||||||
|
- `1` -- inline simple functions
|
||||||
|
- `2` -- inline functions with arguments
|
||||||
|
- `3` -- inline functions with arguments and variables
|
||||||
|
- `true` -- same as `3`
|
||||||
|
|
||||||
- `join_vars` (default: `true`) -- join consecutive `var` statements
|
- `join_vars` (default: `true`) -- join consecutive `var` statements
|
||||||
|
|
||||||
|
|||||||
28
appveyor.yml
28
appveyor.yml
@@ -1,24 +1,20 @@
|
|||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
- nodejs_version: "0.10"
|
- nodejs_version: "0.10"
|
||||||
- nodejs_version: "0.12"
|
- nodejs_version: "0.12"
|
||||||
- nodejs_version: "4.0"
|
- nodejs_version: "4"
|
||||||
- nodejs_version: "6.0"
|
- nodejs_version: "6"
|
||||||
|
- nodejs_version: "8"
|
||||||
|
install:
|
||||||
|
- ps: Install-Product node $env:nodejs_version
|
||||||
|
- set UGLIFYJS_TEST_ALL=1
|
||||||
|
- npm install
|
||||||
|
build: off
|
||||||
|
cache:
|
||||||
|
- tmp
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
||||||
platform:
|
|
||||||
- x86
|
|
||||||
- x64
|
|
||||||
|
|
||||||
install:
|
|
||||||
- ps: Install-Product node $env:nodejs_version $env:platform
|
|
||||||
- npm install
|
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- node --version
|
- node --version
|
||||||
- npm --version
|
- npm --version
|
||||||
- npm test
|
- npm test
|
||||||
|
|
||||||
build: off
|
|
||||||
|
|||||||
32
bin/uglifyjs
32
bin/uglifyjs
@@ -3,11 +3,7 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// workaround for tty output truncation upon process.exit()
|
require("../tools/exit");
|
||||||
[process.stdout, process.stderr].forEach(function(stream){
|
|
||||||
if (stream._handle && stream._handle.setBlocking)
|
|
||||||
stream._handle.setBlocking(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var info = require("../package.json");
|
var info = require("../package.json");
|
||||||
@@ -15,7 +11,7 @@ var path = require("path");
|
|||||||
var program = require("commander");
|
var program = require("commander");
|
||||||
var UglifyJS = require("../tools/node");
|
var UglifyJS = require("../tools/node");
|
||||||
|
|
||||||
var skip_keys = [ "cname", "enclosed", "inlined", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
|
var skip_keys = [ "cname", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
|
||||||
var files = {};
|
var files = {};
|
||||||
var options = {
|
var options = {
|
||||||
compress: false,
|
compress: false,
|
||||||
@@ -238,7 +234,20 @@ function run() {
|
|||||||
}
|
}
|
||||||
fatal(ex);
|
fatal(ex);
|
||||||
} else if (program.output == "ast") {
|
} else if (program.output == "ast") {
|
||||||
|
if (!options.compress && !options.mangle) {
|
||||||
|
result.ast.figure_out_scope({});
|
||||||
|
}
|
||||||
print(JSON.stringify(result.ast, function(key, value) {
|
print(JSON.stringify(result.ast, function(key, value) {
|
||||||
|
if (value) switch (key) {
|
||||||
|
case "thedef":
|
||||||
|
return symdef(value);
|
||||||
|
case "enclosed":
|
||||||
|
return value.length ? value.map(symdef) : undefined;
|
||||||
|
case "variables":
|
||||||
|
case "functions":
|
||||||
|
case "globals":
|
||||||
|
return value.size() ? value.map(symdef) : undefined;
|
||||||
|
}
|
||||||
if (skip_key(key)) return;
|
if (skip_key(key)) return;
|
||||||
if (value instanceof UglifyJS.AST_Token) return;
|
if (value instanceof UglifyJS.AST_Token) return;
|
||||||
if (value instanceof UglifyJS.Dictionary) return;
|
if (value instanceof UglifyJS.Dictionary) return;
|
||||||
@@ -246,6 +255,11 @@ function run() {
|
|||||||
var result = {
|
var result = {
|
||||||
_class: "AST_" + value.TYPE
|
_class: "AST_" + value.TYPE
|
||||||
};
|
};
|
||||||
|
if (value.block_scope) {
|
||||||
|
result.variables = value.block_scope.variables;
|
||||||
|
result.functions = value.block_scope.functions;
|
||||||
|
result.enclosed = value.block_scope.enclosed;
|
||||||
|
}
|
||||||
value.CTOR.PROPS.forEach(function(prop) {
|
value.CTOR.PROPS.forEach(function(prop) {
|
||||||
result[prop] = value[prop];
|
result[prop] = value[prop];
|
||||||
});
|
});
|
||||||
@@ -392,6 +406,12 @@ function skip_key(key) {
|
|||||||
return skip_keys.indexOf(key) >= 0;
|
return skip_keys.indexOf(key) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function symdef(def) {
|
||||||
|
var ret = (1e6 + def.id) + " " + def.name;
|
||||||
|
if (def.mangled_name) ret += " " + def.mangled_name;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
function format_object(obj) {
|
function format_object(obj) {
|
||||||
var lines = [];
|
var lines = [];
|
||||||
var padding = "";
|
var padding = "";
|
||||||
|
|||||||
832
lib/compress.js
832
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,6 @@ function set_shorthand(name, options, keys) {
|
|||||||
|
|
||||||
function init_cache(cache) {
|
function init_cache(cache) {
|
||||||
if (!cache) return;
|
if (!cache) return;
|
||||||
if (!("cname" in cache)) cache.cname = -1;
|
|
||||||
if (!("props" in cache)) {
|
if (!("props" in cache)) {
|
||||||
cache.props = new Dictionary();
|
cache.props = new Dictionary();
|
||||||
} else if (!(cache.props instanceof Dictionary)) {
|
} else if (!(cache.props instanceof Dictionary)) {
|
||||||
@@ -39,7 +38,6 @@ function init_cache(cache) {
|
|||||||
|
|
||||||
function to_json(cache) {
|
function to_json(cache) {
|
||||||
return {
|
return {
|
||||||
cname: cache.cname,
|
|
||||||
props: cache.props.toObject()
|
props: cache.props.toObject()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
195
lib/output.js
195
lib/output.js
@@ -476,79 +476,78 @@ function OutputStream(options) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
var start = node.start;
|
var start = node.start;
|
||||||
if (!start) return;
|
if (!start) return;
|
||||||
if (!(start.comments_before && start.comments_before._dumped === self)) {
|
if (start.comments_before && start.comments_before._dumped === self) return;
|
||||||
var comments = start.comments_before;
|
var comments = start.comments_before;
|
||||||
if (!comments) {
|
if (!comments) {
|
||||||
comments = start.comments_before = [];
|
comments = start.comments_before = [];
|
||||||
}
|
}
|
||||||
comments._dumped = self;
|
comments._dumped = self;
|
||||||
|
|
||||||
if (node instanceof AST_Exit && node.value) {
|
if (node instanceof AST_Exit && node.value) {
|
||||||
var tw = new TreeWalker(function(node) {
|
var tw = new TreeWalker(function(node) {
|
||||||
var parent = tw.parent();
|
var parent = tw.parent();
|
||||||
if (parent instanceof AST_Exit
|
if (parent instanceof AST_Exit
|
||||||
|| parent instanceof AST_Binary && parent.left === node
|
|| parent instanceof AST_Binary && parent.left === node
|
||||||
|| parent.TYPE == "Call" && parent.expression === node
|
|| parent.TYPE == "Call" && parent.expression === node
|
||||||
|| parent instanceof AST_Conditional && parent.condition === node
|
|| parent instanceof AST_Conditional && parent.condition === node
|
||||||
|| parent instanceof AST_Dot && parent.expression === node
|
|| parent instanceof AST_Dot && parent.expression === node
|
||||||
|| parent instanceof AST_Sequence && parent.expressions[0] === node
|
|| parent instanceof AST_Sequence && parent.expressions[0] === node
|
||||||
|| parent instanceof AST_Sub && parent.expression === node
|
|| parent instanceof AST_Sub && parent.expression === node
|
||||||
|| parent instanceof AST_UnaryPostfix) {
|
|| parent instanceof AST_UnaryPostfix) {
|
||||||
if (!node.start) return;
|
if (!node.start) return;
|
||||||
var text = node.start.comments_before;
|
var text = node.start.comments_before;
|
||||||
if (text && text._dumped !== self) {
|
if (text && text._dumped !== self) {
|
||||||
text._dumped = self;
|
text._dumped = self;
|
||||||
comments = comments.concat(text);
|
comments = comments.concat(text);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
});
|
} else {
|
||||||
tw.push(node);
|
return true;
|
||||||
node.value.walk(tw);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current_pos == 0) {
|
|
||||||
if (comments.length > 0 && options.shebang && comments[0].type == "comment5") {
|
|
||||||
print("#!" + comments.shift().value + "\n");
|
|
||||||
indent();
|
|
||||||
}
|
|
||||||
var preamble = options.preamble;
|
|
||||||
if (preamble) {
|
|
||||||
print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
comments = comments.filter(comment_filter, node);
|
|
||||||
if (comments.length == 0) return;
|
|
||||||
var last_nlb = /(^|\n) *$/.test(OUTPUT);
|
|
||||||
comments.forEach(function(c, i) {
|
|
||||||
if (!last_nlb) {
|
|
||||||
if (c.nlb) {
|
|
||||||
print("\n");
|
|
||||||
indent();
|
|
||||||
last_nlb = true;
|
|
||||||
} else if (i > 0) {
|
|
||||||
space();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (/comment[134]/.test(c.type)) {
|
|
||||||
print("//" + c.value.replace(/[@#]__PURE__/g, ' ') + "\n");
|
|
||||||
indent();
|
|
||||||
last_nlb = true;
|
|
||||||
} else if (c.type == "comment2") {
|
|
||||||
print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/");
|
|
||||||
last_nlb = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
tw.push(node);
|
||||||
|
node.value.walk(tw);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_pos == 0) {
|
||||||
|
if (comments.length > 0 && options.shebang && comments[0].type == "comment5") {
|
||||||
|
print("#!" + comments.shift().value + "\n");
|
||||||
|
indent();
|
||||||
|
}
|
||||||
|
var preamble = options.preamble;
|
||||||
|
if (preamble) {
|
||||||
|
print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
comments = comments.filter(comment_filter, node);
|
||||||
|
if (comments.length == 0) return;
|
||||||
|
var last_nlb = /(^|\n) *$/.test(OUTPUT);
|
||||||
|
comments.forEach(function(c, i) {
|
||||||
if (!last_nlb) {
|
if (!last_nlb) {
|
||||||
if (start.nlb) {
|
if (c.nlb) {
|
||||||
print("\n");
|
print("\n");
|
||||||
indent();
|
indent();
|
||||||
} else {
|
last_nlb = true;
|
||||||
|
} else if (i > 0) {
|
||||||
space();
|
space();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (/comment[134]/.test(c.type)) {
|
||||||
|
print("//" + c.value.replace(/[@#]__PURE__/g, ' ') + "\n");
|
||||||
|
indent();
|
||||||
|
last_nlb = true;
|
||||||
|
} else if (c.type == "comment2") {
|
||||||
|
print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/");
|
||||||
|
last_nlb = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!last_nlb) {
|
||||||
|
if (start.nlb) {
|
||||||
|
print("\n");
|
||||||
|
indent();
|
||||||
|
} else {
|
||||||
|
space();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,31 +556,33 @@ function OutputStream(options) {
|
|||||||
var token = node.end;
|
var token = node.end;
|
||||||
if (!token) return;
|
if (!token) return;
|
||||||
var comments = token[tail ? "comments_before" : "comments_after"];
|
var comments = token[tail ? "comments_before" : "comments_after"];
|
||||||
if (comments && comments._dumped !== self) {
|
if (!comments || comments._dumped === self) return;
|
||||||
comments._dumped = self;
|
if (!(node instanceof AST_Statement || all(comments, function(c) {
|
||||||
var insert = OUTPUT.length;
|
return !/comment[134]/.test(c.type);
|
||||||
comments.filter(comment_filter, node).forEach(function(c, i) {
|
}))) return;
|
||||||
need_space = false;
|
comments._dumped = self;
|
||||||
if (need_newline_indented) {
|
var insert = OUTPUT.length;
|
||||||
print("\n");
|
comments.filter(comment_filter, node).forEach(function(c, i) {
|
||||||
indent();
|
need_space = false;
|
||||||
need_newline_indented = false;
|
if (need_newline_indented) {
|
||||||
} else if (c.nlb && (i > 0 || !/(^|\n) *$/.test(OUTPUT))) {
|
print("\n");
|
||||||
print("\n");
|
indent();
|
||||||
indent();
|
need_newline_indented = false;
|
||||||
} else if (i > 0 || !tail) {
|
} else if (c.nlb && (i > 0 || !/(^|\n) *$/.test(OUTPUT))) {
|
||||||
space();
|
print("\n");
|
||||||
}
|
indent();
|
||||||
if (/comment[134]/.test(c.type)) {
|
} else if (i > 0 || !tail) {
|
||||||
print("//" + c.value.replace(/[@#]__PURE__/g, ' '));
|
space();
|
||||||
need_newline_indented = true;
|
}
|
||||||
} else if (c.type == "comment2") {
|
if (/comment[134]/.test(c.type)) {
|
||||||
print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/");
|
print("//" + c.value.replace(/[@#]__PURE__/g, ' '));
|
||||||
need_space = true;
|
need_newline_indented = true;
|
||||||
}
|
} else if (c.type == "comment2") {
|
||||||
});
|
print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/");
|
||||||
if (OUTPUT.length > insert) newline_insert = insert;
|
need_space = true;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
if (OUTPUT.length > insert) newline_insert = insert;
|
||||||
}
|
}
|
||||||
|
|
||||||
var stack = [];
|
var stack = [];
|
||||||
@@ -627,7 +628,7 @@ function OutputStream(options) {
|
|||||||
add_mapping : add_mapping,
|
add_mapping : add_mapping,
|
||||||
option : function(opt) { return options[opt] },
|
option : function(opt) { return options[opt] },
|
||||||
prepend_comments: readonly ? noop : prepend_comments,
|
prepend_comments: readonly ? noop : prepend_comments,
|
||||||
append_comments : readonly ? noop : append_comments,
|
append_comments : readonly || comment_filter === return_false ? noop : append_comments,
|
||||||
line : function() { return current_line },
|
line : function() { return current_line },
|
||||||
col : function() { return current_col },
|
col : function() { return current_col },
|
||||||
pos : function() { return current_pos },
|
pos : function() { return current_pos },
|
||||||
@@ -699,9 +700,7 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PARENS(AST_Node, function(){
|
PARENS(AST_Node, return_false);
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
// a function expression needs parens around it when it's provably
|
// a function expression needs parens around it when it's provably
|
||||||
// the first token to appear in a statement.
|
// the first token to appear in a statement.
|
||||||
@@ -730,15 +729,9 @@ function OutputStream(options) {
|
|||||||
return p instanceof AST_PropAccess && p.expression === this;
|
return p instanceof AST_PropAccess && p.expression === this;
|
||||||
});
|
});
|
||||||
|
|
||||||
PARENS(AST_ClassExpression, function(output){
|
|
||||||
return output.parent() instanceof AST_SimpleStatement;
|
|
||||||
});
|
|
||||||
|
|
||||||
// same goes for an object literal, because otherwise it would be
|
// same goes for an object literal, because otherwise it would be
|
||||||
// interpreted as a block of code.
|
// interpreted as a block of code.
|
||||||
PARENS(AST_Object, function(output){
|
PARENS([ AST_ClassExpression, AST_Object ], first_in_statement);
|
||||||
return first_in_statement(output);
|
|
||||||
});
|
|
||||||
|
|
||||||
PARENS(AST_Unary, function(output){
|
PARENS(AST_Unary, function(output){
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
@@ -805,6 +798,10 @@ function OutputStream(options) {
|
|||||||
// a = yield 3
|
// a = yield 3
|
||||||
if (p instanceof AST_Binary && p.operator !== "=")
|
if (p instanceof AST_Binary && p.operator !== "=")
|
||||||
return true;
|
return true;
|
||||||
|
// (yield 1)()
|
||||||
|
// new (yield 1)()
|
||||||
|
if (p instanceof AST_Call && p.expression === this)
|
||||||
|
return true;
|
||||||
// (yield 1) ? yield 2 : yield 3
|
// (yield 1) ? yield 2 : yield 3
|
||||||
if (p instanceof AST_Conditional && p.condition === this)
|
if (p instanceof AST_Conditional && p.condition === this)
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
87
lib/parse.js
87
lib/parse.js
@@ -1168,10 +1168,6 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
function labeled_statement() {
|
function labeled_statement() {
|
||||||
var label = as_symbol(AST_Label);
|
var label = as_symbol(AST_Label);
|
||||||
if (label.name === "yield" && is_in_generator()) {
|
|
||||||
// Ecma-262, 12.1.1 Static Semantics: Early Errors
|
|
||||||
token_error(S.prev, "Yield cannot be used as label inside generators");
|
|
||||||
}
|
|
||||||
if (label.name === "await" && is_in_async()) {
|
if (label.name === "await" && is_in_async()) {
|
||||||
token_error(S.prev, "await cannot be used as label inside async function");
|
token_error(S.prev, "await cannot be used as label inside async function");
|
||||||
}
|
}
|
||||||
@@ -1331,7 +1327,7 @@ function parse($TEXT, options) {
|
|||||||
if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
|
if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
|
||||||
unexpected(prev());
|
unexpected(prev());
|
||||||
|
|
||||||
var args = parameters();
|
var args = [];
|
||||||
var body = _function_body(true, is_generator || is_generator_property, is_async, name, args);
|
var body = _function_body(true, is_generator || is_generator_property, is_async, name, args);
|
||||||
return new ctor({
|
return new ctor({
|
||||||
start : args.start,
|
start : args.start,
|
||||||
@@ -1402,9 +1398,8 @@ function parse($TEXT, options) {
|
|||||||
return tracker;
|
return tracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parameters() {
|
function parameters(params) {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
var params = [];
|
|
||||||
var used_parameters = track_used_binding_identifiers(true, S.input.has_directive("use strict"));
|
var used_parameters = track_used_binding_identifiers(true, S.input.has_directive("use strict"));
|
||||||
|
|
||||||
expect("(");
|
expect("(");
|
||||||
@@ -1424,7 +1419,6 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
return params;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function parameter(used_parameters, symbol_type) {
|
function parameter(used_parameters, symbol_type) {
|
||||||
@@ -1511,12 +1505,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
} else if (is("name")) {
|
} else if (is("name")) {
|
||||||
used_parameters.add_parameter(S.token);
|
used_parameters.add_parameter(S.token);
|
||||||
elements.push(new symbol_type({
|
elements.push(as_symbol(symbol_type));
|
||||||
start: S.token,
|
|
||||||
name: S.token.value,
|
|
||||||
end: S.token
|
|
||||||
}));
|
|
||||||
next();
|
|
||||||
} else {
|
} else {
|
||||||
croak("Invalid function parameter");
|
croak("Invalid function parameter");
|
||||||
}
|
}
|
||||||
@@ -1566,11 +1555,8 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
if (is("name") && (is_token(peek(), "punc") || is_token(peek(), "operator")) && [",", "}", "="].indexOf(peek().value) !== -1) {
|
if (is("name") && (is_token(peek(), "punc") || is_token(peek(), "operator")) && [",", "}", "="].indexOf(peek().value) !== -1) {
|
||||||
used_parameters.add_parameter(S.token);
|
used_parameters.add_parameter(S.token);
|
||||||
var value = new symbol_type({
|
var start = prev();
|
||||||
start: S.token,
|
var value = as_symbol(symbol_type);
|
||||||
name: S.token.value,
|
|
||||||
end: S.token,
|
|
||||||
});
|
|
||||||
if (is_expand) {
|
if (is_expand) {
|
||||||
elements.push(new AST_Expansion({
|
elements.push(new AST_Expansion({
|
||||||
start: expand_token,
|
start: expand_token,
|
||||||
@@ -1579,13 +1565,12 @@ function parse($TEXT, options) {
|
|||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
elements.push(new AST_ObjectKeyVal({
|
elements.push(new AST_ObjectKeyVal({
|
||||||
start: prev(),
|
start: start,
|
||||||
key: S.token.value,
|
key: value.name,
|
||||||
value: value,
|
value: value,
|
||||||
end: value.end,
|
end: value.end,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
next();
|
|
||||||
} else if (is("punc", "}")) {
|
} else if (is("punc", "}")) {
|
||||||
continue; // Allow trailing hole
|
continue; // Allow trailing hole
|
||||||
} else {
|
} else {
|
||||||
@@ -1642,12 +1627,7 @@ function parse($TEXT, options) {
|
|||||||
});
|
});
|
||||||
} else if (is("name")) {
|
} else if (is("name")) {
|
||||||
used_parameters.add_parameter(S.token);
|
used_parameters.add_parameter(S.token);
|
||||||
next();
|
return as_symbol(symbol_type);
|
||||||
return new symbol_type({
|
|
||||||
start: prev(),
|
|
||||||
name: prev().value,
|
|
||||||
end: prev()
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
croak("Invalid function parameter");
|
croak("Invalid function parameter");
|
||||||
}
|
}
|
||||||
@@ -1701,6 +1681,7 @@ function parse($TEXT, options) {
|
|||||||
S.in_generator = S.in_function;
|
S.in_generator = S.in_function;
|
||||||
if (is_async)
|
if (is_async)
|
||||||
S.in_async = S.in_function;
|
S.in_async = S.in_function;
|
||||||
|
if (args) parameters(args);
|
||||||
if (block)
|
if (block)
|
||||||
S.in_directives = true;
|
S.in_directives = true;
|
||||||
S.in_loop = 0;
|
S.in_loop = 0;
|
||||||
@@ -1708,10 +1689,8 @@ function parse($TEXT, options) {
|
|||||||
if (block) {
|
if (block) {
|
||||||
S.input.push_directives_stack();
|
S.input.push_directives_stack();
|
||||||
var a = block_();
|
var a = block_();
|
||||||
if (S.input.has_directive("use strict")) {
|
if (name) _verify_symbol(name);
|
||||||
if (name) strict_verify_symbol(name);
|
if (args) args.forEach(_verify_symbol);
|
||||||
if (args) args.forEach(strict_verify_symbol);
|
|
||||||
}
|
|
||||||
S.input.pop_directives_stack();
|
S.input.pop_directives_stack();
|
||||||
} else {
|
} else {
|
||||||
var a = expression(false);
|
var a = expression(false);
|
||||||
@@ -1883,7 +1862,7 @@ function parse($TEXT, options) {
|
|||||||
name : as_symbol(sym_type),
|
name : as_symbol(sym_type),
|
||||||
value : is("operator", "=")
|
value : is("operator", "=")
|
||||||
? (next(), expression(false, no_in))
|
? (next(), expression(false, no_in))
|
||||||
: !no_in && kind === "const" && S.input.has_directive("use strict")
|
: !no_in && kind === "const"
|
||||||
? croak("Missing initializer in const declaration") : null,
|
? croak("Missing initializer in const declaration") : null,
|
||||||
end : prev()
|
end : prev()
|
||||||
});
|
});
|
||||||
@@ -1939,12 +1918,14 @@ function parse($TEXT, options) {
|
|||||||
} else {
|
} else {
|
||||||
args = [];
|
args = [];
|
||||||
}
|
}
|
||||||
return subscripts(new AST_New({
|
var call = new AST_New({
|
||||||
start : start,
|
start : start,
|
||||||
expression : newexp,
|
expression : newexp,
|
||||||
args : args,
|
args : args,
|
||||||
end : prev()
|
end : prev()
|
||||||
}), allow_calls);
|
});
|
||||||
|
mark_pure(call);
|
||||||
|
return subscripts(call, allow_calls);
|
||||||
};
|
};
|
||||||
|
|
||||||
function as_atom_node() {
|
function as_atom_node() {
|
||||||
@@ -2593,9 +2574,14 @@ function parse($TEXT, options) {
|
|||||||
unexpected(tmp);
|
unexpected(tmp);
|
||||||
}
|
}
|
||||||
case "name":
|
case "name":
|
||||||
if (tmp.value == "yield" && !is_token(peek(), "punc", ":") && !is_token(peek(), "punc", "(")
|
if (tmp.value == "yield") {
|
||||||
&& S.input.has_directive("use strict") && !is_in_generator()) {
|
if (is_in_generator()) {
|
||||||
token_error(tmp, "Unexpected yield identifier inside strict mode");
|
token_error(tmp, "Yield cannot be used as identifier inside generators");
|
||||||
|
} else if (!is_token(peek(), "punc", ":")
|
||||||
|
&& !is_token(peek(), "punc", "(")
|
||||||
|
&& S.input.has_directive("use strict")) {
|
||||||
|
token_error(tmp, "Unexpected yield identifier inside strict mode");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case "string":
|
case "string":
|
||||||
case "num":
|
case "num":
|
||||||
@@ -2626,9 +2612,19 @@ function parse($TEXT, options) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function strict_verify_symbol(sym) {
|
function _verify_symbol(sym) {
|
||||||
if (sym.name == "arguments" || sym.name == "eval")
|
var name = sym.name;
|
||||||
croak("Unexpected " + sym.name + " in strict mode", sym.start.line, sym.start.col, sym.start.pos);
|
if (is_in_generator() && name == "yield") {
|
||||||
|
token_error(sym.start, "Yield cannot be used as identifier inside generators");
|
||||||
|
}
|
||||||
|
if (S.input.has_directive("use strict")) {
|
||||||
|
if (name == "yield") {
|
||||||
|
token_error(sym.start, "Unexpected yield identifier inside strict mode");
|
||||||
|
}
|
||||||
|
if (sym instanceof AST_SymbolDeclaration && (name == "arguments" || name == "eval")) {
|
||||||
|
token_error(sym.start, "Unexpected " + name + " in strict mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function as_symbol(type, noerror) {
|
function as_symbol(type, noerror) {
|
||||||
@@ -2636,13 +2632,8 @@ function parse($TEXT, options) {
|
|||||||
if (!noerror) croak("Name expected");
|
if (!noerror) croak("Name expected");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (is("name", "yield") && S.input.has_directive("use strict")) {
|
|
||||||
token_error(S.prev, "Unexpected yield identifier inside strict mode");
|
|
||||||
}
|
|
||||||
var sym = _make_symbol(type);
|
var sym = _make_symbol(type);
|
||||||
if (S.input.has_directive("use strict") && sym instanceof AST_SymbolDeclaration) {
|
_verify_symbol(sym);
|
||||||
strict_verify_symbol(sym);
|
|
||||||
}
|
|
||||||
next();
|
next();
|
||||||
return sym;
|
return sym;
|
||||||
};
|
};
|
||||||
@@ -2870,7 +2861,7 @@ function parse($TEXT, options) {
|
|||||||
next();
|
next();
|
||||||
return _yield_expression();
|
return _yield_expression();
|
||||||
} else if (S.input.has_directive("use strict")) {
|
} else if (S.input.has_directive("use strict")) {
|
||||||
token_error(S.token, "Unexpected yield identifier inside strict mode")
|
token_error(S.token, "Unexpected yield identifier inside strict mode");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -130,12 +130,15 @@ function mangle_properties(ast, options) {
|
|||||||
if (!Array.isArray(reserved)) reserved = [];
|
if (!Array.isArray(reserved)) reserved = [];
|
||||||
if (!options.builtins) find_builtins(reserved);
|
if (!options.builtins) find_builtins(reserved);
|
||||||
|
|
||||||
var cache = options.cache;
|
var cname = -1;
|
||||||
if (cache == null) {
|
var cache;
|
||||||
cache = {
|
if (options.cache) {
|
||||||
cname: -1,
|
cache = options.cache.props;
|
||||||
props: new Dictionary()
|
cache.each(function(mangled_name) {
|
||||||
};
|
push_uniq(reserved, mangled_name);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
cache = new Dictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
var regex = options.regex;
|
var regex = options.regex;
|
||||||
@@ -192,7 +195,7 @@ function mangle_properties(ast, options) {
|
|||||||
if (unmangleable.indexOf(name) >= 0) return false;
|
if (unmangleable.indexOf(name) >= 0) return false;
|
||||||
if (reserved.indexOf(name) >= 0) return false;
|
if (reserved.indexOf(name) >= 0) return false;
|
||||||
if (options.only_cache) {
|
if (options.only_cache) {
|
||||||
return cache.props.has(name);
|
return cache.has(name);
|
||||||
}
|
}
|
||||||
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
|
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
|
||||||
return true;
|
return true;
|
||||||
@@ -201,7 +204,7 @@ function mangle_properties(ast, options) {
|
|||||||
function should_mangle(name) {
|
function should_mangle(name) {
|
||||||
if (regex && !regex.test(name)) return false;
|
if (regex && !regex.test(name)) return false;
|
||||||
if (reserved.indexOf(name) >= 0) return false;
|
if (reserved.indexOf(name) >= 0) return false;
|
||||||
return cache.props.has(name)
|
return cache.has(name)
|
||||||
|| names_to_mangle.indexOf(name) >= 0;
|
|| names_to_mangle.indexOf(name) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +222,7 @@ function mangle_properties(ast, options) {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
var mangled = cache.props.get(name);
|
var mangled = cache.get(name);
|
||||||
if (!mangled) {
|
if (!mangled) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
||||||
@@ -233,11 +236,11 @@ function mangle_properties(ast, options) {
|
|||||||
// either debug mode is off, or it is on and we could not use the mangled name
|
// either debug mode is off, or it is on and we could not use the mangled name
|
||||||
if (!mangled) {
|
if (!mangled) {
|
||||||
do {
|
do {
|
||||||
mangled = base54(++cache.cname);
|
mangled = base54(++cname);
|
||||||
} while (!can_mangle(mangled));
|
} while (!can_mangle(mangled));
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.props.set(name, mangled);
|
cache.set(name, mangled);
|
||||||
}
|
}
|
||||||
return mangled;
|
return mangled;
|
||||||
}
|
}
|
||||||
|
|||||||
138
lib/scope.js
138
lib/scope.js
@@ -43,9 +43,10 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function SymbolDef(scope, orig) {
|
function SymbolDef(scope, orig, init) {
|
||||||
this.name = orig.name;
|
this.name = orig.name;
|
||||||
this.orig = [ orig ];
|
this.orig = [ orig ];
|
||||||
|
this.init = init;
|
||||||
this.eliminated = 0;
|
this.eliminated = 0;
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.references = [];
|
this.references = [];
|
||||||
@@ -175,7 +176,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
node.references = [];
|
node.references = [];
|
||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolLambda) {
|
if (node instanceof AST_SymbolLambda) {
|
||||||
defun.def_function(node);
|
defun.def_function(node, node.name == "arguments" ? undefined : defun);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolDefun) {
|
else if (node instanceof AST_SymbolDefun) {
|
||||||
// Careful here, the scope where this should be defined is
|
// Careful here, the scope where this should be defined is
|
||||||
@@ -183,10 +184,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
// scope when we encounter the AST_Defun node (which is
|
// scope when we encounter the AST_Defun node (which is
|
||||||
// instanceof AST_Scope) but we get to the symbol a bit
|
// instanceof AST_Scope) but we get to the symbol a bit
|
||||||
// later.
|
// later.
|
||||||
mark_export((node.scope = defun.parent_scope.get_defun_scope()).def_function(node), 1);
|
mark_export((node.scope = defun.parent_scope.get_defun_scope()).def_function(node, defun), 1);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolClass) {
|
else if (node instanceof AST_SymbolClass) {
|
||||||
mark_export(defun.def_variable(node), 1);
|
mark_export(defun.def_variable(node, defun), 1);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolImport) {
|
else if (node instanceof AST_SymbolImport) {
|
||||||
scope.def_variable(node);
|
scope.def_variable(node);
|
||||||
@@ -194,12 +195,17 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
else if (node instanceof AST_SymbolDefClass) {
|
else if (node instanceof AST_SymbolDefClass) {
|
||||||
// This deals with the name of the class being available
|
// This deals with the name of the class being available
|
||||||
// inside the class.
|
// inside the class.
|
||||||
mark_export((node.scope = defun.parent_scope).def_function(node), 1);
|
mark_export((node.scope = defun.parent_scope).def_function(node, defun), 1);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolVar
|
else if (node instanceof AST_SymbolVar
|
||||||
|| node instanceof AST_SymbolLet
|
|| node instanceof AST_SymbolLet
|
||||||
|| node instanceof AST_SymbolConst) {
|
|| node instanceof AST_SymbolConst) {
|
||||||
var def = ((node instanceof AST_SymbolBlockDeclaration) ? scope : defun).def_variable(node);
|
var def;
|
||||||
|
if (node instanceof AST_SymbolBlockDeclaration) {
|
||||||
|
def = scope.def_variable(node, null);
|
||||||
|
} else {
|
||||||
|
def = defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
|
||||||
|
}
|
||||||
if (!all(def.orig, function(sym) {
|
if (!all(def.orig, function(sym) {
|
||||||
if (sym === node) return true;
|
if (sym === node) return true;
|
||||||
if (node instanceof AST_SymbolBlockDeclaration) {
|
if (node instanceof AST_SymbolBlockDeclaration) {
|
||||||
@@ -284,6 +290,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
}
|
}
|
||||||
node.thedef = sym;
|
node.thedef = sym;
|
||||||
node.reference(options);
|
node.reference(options);
|
||||||
|
if (node.scope.is_block_scope()
|
||||||
|
&& !(sym.orig[0] instanceof AST_SymbolBlockDeclaration)) {
|
||||||
|
node.scope = node.scope.get_defun_scope();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// ensure mangling works if catch reuses a scope variable
|
// ensure mangling works if catch reuses a scope variable
|
||||||
@@ -330,10 +340,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.cache) {
|
|
||||||
this.cname = options.cache.cname;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("def_global", function(node){
|
AST_Toplevel.DEFMETHOD("def_global", function(node){
|
||||||
@@ -403,29 +409,32 @@ AST_Scope.DEFMETHOD("find_variable", function(name){
|
|||||||
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
AST_Scope.DEFMETHOD("def_function", function(symbol, init){
|
||||||
var def = this.def_variable(symbol);
|
var def = this.def_variable(symbol, init);
|
||||||
|
if (!def.init) def.init = init;
|
||||||
this.functions.set(symbol.name, def);
|
this.functions.set(symbol.name, def);
|
||||||
return def;
|
return def;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
AST_Scope.DEFMETHOD("def_variable", function(symbol, init){
|
||||||
var def;
|
var def = this.variables.get(symbol.name);
|
||||||
if (!this.variables.has(symbol.name)) {
|
if (def) {
|
||||||
def = new SymbolDef(this, symbol);
|
def.orig.push(symbol);
|
||||||
|
if (def.init && (def.scope !== symbol.scope || def.init instanceof AST_Function)) {
|
||||||
|
def.init = init;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
def = new SymbolDef(this, symbol, init);
|
||||||
this.variables.set(symbol.name, def);
|
this.variables.set(symbol.name, def);
|
||||||
def.global = !this.parent_scope;
|
def.global = !this.parent_scope;
|
||||||
} else {
|
|
||||||
def = this.variables.get(symbol.name);
|
|
||||||
def.orig.push(symbol);
|
|
||||||
}
|
}
|
||||||
return symbol.thedef = def;
|
return symbol.thedef = def;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("next_mangled", function(options){
|
function next_mangled(scope, options) {
|
||||||
var ext = this.enclosed;
|
var ext = scope.enclosed;
|
||||||
out: while (true) {
|
out: while (true) {
|
||||||
var m = base54(++this.cname);
|
var m = base54(++scope.cname);
|
||||||
if (!is_identifier(m)) continue; // skip over "do"
|
if (!is_identifier(m)) continue; // skip over "do"
|
||||||
|
|
||||||
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
||||||
@@ -442,6 +451,18 @@ AST_Scope.DEFMETHOD("next_mangled", function(options){
|
|||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AST_Scope.DEFMETHOD("next_mangled", function(options){
|
||||||
|
return next_mangled(this, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Toplevel.DEFMETHOD("next_mangled", function(options){
|
||||||
|
var name;
|
||||||
|
do {
|
||||||
|
name = next_mangled(this, options);
|
||||||
|
} while (member(name, this.mangled_names));
|
||||||
|
return name;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
||||||
@@ -455,7 +476,7 @@ AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
|||||||
var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
|
var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
var name = AST_Lambda.prototype.next_mangled.call(this, options, def);
|
var name = next_mangled(this, options);
|
||||||
if (!tricky_name || tricky_name != name)
|
if (!tricky_name || tricky_name != name)
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@@ -507,8 +528,14 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
var lname = -1;
|
var lname = -1;
|
||||||
var to_mangle = [];
|
var to_mangle = [];
|
||||||
|
|
||||||
|
var mangled_names = this.mangled_names = [];
|
||||||
if (options.cache) {
|
if (options.cache) {
|
||||||
this.globals.each(collect);
|
this.globals.each(collect);
|
||||||
|
if (options.cache.props) {
|
||||||
|
options.cache.props.each(function(mangled_name) {
|
||||||
|
push_uniq(mangled_names, mangled_name);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
@@ -523,28 +550,23 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
node.variables.each(collect);
|
node.variables.each(collect);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (node.is_block_scope()) {
|
||||||
|
node.block_scope.variables.each(collect);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (node instanceof AST_Label) {
|
if (node instanceof AST_Label) {
|
||||||
var name;
|
var name;
|
||||||
do name = base54(++lname); while (!is_identifier(name));
|
do name = base54(++lname); while (!is_identifier(name));
|
||||||
node.mangled_name = name;
|
node.mangled_name = name;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
var mangle_with_block_scope =
|
if (!options.ie8 && node instanceof AST_SymbolCatch) {
|
||||||
(!options.ie8 && node instanceof AST_SymbolCatch) ||
|
|
||||||
node instanceof AST_SymbolBlockDeclaration;
|
|
||||||
if (mangle_with_block_scope && options.reserved.indexOf(node.name) < 0) {
|
|
||||||
to_mangle.push(node.definition());
|
to_mangle.push(node.definition());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.walk(tw);
|
this.walk(tw);
|
||||||
to_mangle.forEach(function(def){
|
to_mangle.forEach(function(def){ def.mangle(options) });
|
||||||
def.mangle(options);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (options.cache) {
|
|
||||||
options.cache.cname = this.cname;
|
|
||||||
}
|
|
||||||
|
|
||||||
function collect(symbol) {
|
function collect(symbol) {
|
||||||
if (!member(symbol.name, options.reserved)) {
|
if (!member(symbol.name, options.reserved)) {
|
||||||
@@ -553,59 +575,55 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("find_unique_prefix", function(options) {
|
AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
|
||||||
var letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_";
|
|
||||||
var cache = options.cache && options.cache.props;
|
var cache = options.cache && options.cache.props;
|
||||||
var prefixes = Object.create(null);
|
var avoid = Object.create(null);
|
||||||
options.reserved.forEach(add_prefix);
|
options.reserved.forEach(to_avoid);
|
||||||
this.globals.each(add_def);
|
this.globals.each(add_def);
|
||||||
this.walk(new TreeWalker(function(node) {
|
this.walk(new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_Scope) node.variables.each(add_def);
|
if (node instanceof AST_Scope) node.variables.each(add_def);
|
||||||
if (node instanceof AST_SymbolCatch) add_def(node.definition());
|
if (node instanceof AST_SymbolCatch) add_def(node.definition());
|
||||||
}));
|
}));
|
||||||
var prefix, i = 0;
|
return avoid;
|
||||||
do {
|
|
||||||
prefix = create_name(i++);
|
|
||||||
} while (prefixes[prefix]);
|
|
||||||
return prefix;
|
|
||||||
|
|
||||||
function add_prefix(name) {
|
function to_avoid(name) {
|
||||||
if (/[0-9]$/.test(name)) {
|
avoid[name] = true;
|
||||||
prefixes[name.replace(/[0-9]+$/, "")] = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_def(def) {
|
function add_def(def) {
|
||||||
var name = def.name;
|
var name = def.name;
|
||||||
if (def.global && cache && cache.has(name)) name = cache.get(name);
|
if (def.global && cache && cache.has(name)) name = cache.get(name);
|
||||||
else if (!def.unmangleable(options)) return;
|
else if (!def.unmangleable(options)) return;
|
||||||
add_prefix(name);
|
to_avoid(name);
|
||||||
}
|
|
||||||
|
|
||||||
function create_name(num) {
|
|
||||||
var name = "";
|
|
||||||
do {
|
|
||||||
name += letters[num % letters.length];
|
|
||||||
num = Math.floor(num / letters.length);
|
|
||||||
} while (num);
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
||||||
|
base54.reset();
|
||||||
|
base54.sort();
|
||||||
options = this._default_mangler_options(options);
|
options = this._default_mangler_options(options);
|
||||||
var prefix = this.find_unique_prefix(options);
|
var avoid = this.find_colliding_names(options);
|
||||||
|
var cname = 0;
|
||||||
this.globals.each(rename);
|
this.globals.each(rename);
|
||||||
this.walk(new TreeWalker(function(node) {
|
this.walk(new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_Scope) node.variables.each(rename);
|
if (node instanceof AST_Scope) node.variables.each(rename);
|
||||||
if (node instanceof AST_SymbolCatch) rename(node.definition());
|
if (node instanceof AST_SymbolCatch) rename(node.definition());
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
function next_name() {
|
||||||
|
var name;
|
||||||
|
do {
|
||||||
|
name = base54(cname++);
|
||||||
|
} while (avoid[name] || !is_identifier(name));
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
function rename(def) {
|
function rename(def) {
|
||||||
if (def.global || def.unmangleable(options)) return;
|
if (def.global && options.cache) return;
|
||||||
|
if (def.unmangleable(options)) return;
|
||||||
if (member(def.name, options.reserved)) return;
|
if (member(def.name, options.reserved)) return;
|
||||||
var d = def.redefined();
|
var d = def.redefined();
|
||||||
def.name = d ? d.name : prefix + def.id;
|
def.name = d ? d.name : next_name();
|
||||||
def.orig.forEach(function(sym) {
|
def.orig.forEach(function(sym) {
|
||||||
sym.name = def.name;
|
sym.name = def.name;
|
||||||
});
|
});
|
||||||
|
|||||||
12
package.json
12
package.json
@@ -4,17 +4,15 @@
|
|||||||
"homepage": "https://github.com/mishoo/UglifyJS2/tree/harmony",
|
"homepage": "https://github.com/mishoo/UglifyJS2/tree/harmony",
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "3.3.2",
|
"version": "3.3.7",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
"maintainers": [
|
"maintainers": [
|
||||||
|
"Alex Lam <alexlamsl@gmail.com>",
|
||||||
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
|
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
|
||||||
],
|
],
|
||||||
"repository": "git+https://github.com/mishoo/UglifyJS2.git#harmony",
|
"repository": "https://github.com/mishoo/UglifyJS2.git#harmony",
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/mishoo/UglifyJS2/issues"
|
|
||||||
},
|
|
||||||
"main": "tools/node.js",
|
"main": "tools/node.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
"uglifyjs": "bin/uglifyjs"
|
"uglifyjs": "bin/uglifyjs"
|
||||||
@@ -26,11 +24,11 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": "~2.12.1",
|
"commander": "~2.13.0",
|
||||||
"source-map": "~0.6.1"
|
"source-map": "~0.6.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~5.2.1",
|
"acorn": "~5.3.0",
|
||||||
"mocha": "~3.5.1",
|
"mocha": "~3.5.1",
|
||||||
"semver": "~5.4.1"
|
"semver": "~5.4.1"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ do_not_remove_anon_blocks_if_they_have_decls: {
|
|||||||
var x;
|
var x;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const y;
|
const y = 1;
|
||||||
class Zee {};
|
class Zee {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ do_not_remove_anon_blocks_if_they_have_decls: {
|
|||||||
}
|
}
|
||||||
var x;
|
var x;
|
||||||
{
|
{
|
||||||
const y;
|
const y = 1;
|
||||||
class Zee {}
|
class Zee {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,12 +77,12 @@ remove_unused_in_global_block: {
|
|||||||
input: {
|
input: {
|
||||||
{
|
{
|
||||||
let x;
|
let x;
|
||||||
const y;
|
const y = 1;
|
||||||
class Zee {};
|
class Zee {};
|
||||||
var w;
|
var w;
|
||||||
}
|
}
|
||||||
let ex;
|
let ex;
|
||||||
const why;
|
const why = 2;
|
||||||
class Zed {};
|
class Zed {};
|
||||||
var wut;
|
var wut;
|
||||||
console.log(x, y, Zee);
|
console.log(x, y, Zee);
|
||||||
@@ -90,7 +90,7 @@ remove_unused_in_global_block: {
|
|||||||
expect: {
|
expect: {
|
||||||
var w;
|
var w;
|
||||||
let ex;
|
let ex;
|
||||||
const why;
|
const why = 2;
|
||||||
class Zed {};
|
class Zed {};
|
||||||
var wut;
|
var wut;
|
||||||
console.log(x, y, Zee);
|
console.log(x, y, Zee);
|
||||||
|
|||||||
@@ -2296,6 +2296,7 @@ toplevel_single_reference: {
|
|||||||
unused_orig: {
|
unused_orig: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
dead_code: true,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -2323,7 +2324,7 @@ unused_orig: {
|
|||||||
var c = b;
|
var c = b;
|
||||||
for (var d in c) {
|
for (var d in c) {
|
||||||
var a;
|
var a;
|
||||||
return --b + (a = c[0]);
|
return --b + c[0];
|
||||||
}
|
}
|
||||||
a && a.NaN;
|
a && a.NaN;
|
||||||
}([2]), a);
|
}([2]), a);
|
||||||
@@ -4180,10 +4181,9 @@ recursive_function_replacement: {
|
|||||||
console.log(f(c));
|
console.log(f(c));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f(n) {
|
console.log(function n(o) {
|
||||||
return x(y(f(n)));
|
return x(y(n(o)));
|
||||||
}
|
}(c));
|
||||||
console.log(f(c));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1203,3 +1203,67 @@ issue_2560: {
|
|||||||
"2",
|
"2",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hoist_decl: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
join_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (x()) {
|
||||||
|
var a;
|
||||||
|
y();
|
||||||
|
} else {
|
||||||
|
z();
|
||||||
|
var b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, b;
|
||||||
|
x() ? y() : z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
to_and_or: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var values = [
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
"foo",
|
||||||
|
false,
|
||||||
|
-1 / 0,
|
||||||
|
void 0,
|
||||||
|
];
|
||||||
|
values.forEach(function(x) {
|
||||||
|
values.forEach(function(y) {
|
||||||
|
values.forEach(function(z) {
|
||||||
|
console.log(x ? y || z : z);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var values = [
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
"foo",
|
||||||
|
false,
|
||||||
|
-1 / 0,
|
||||||
|
void 0,
|
||||||
|
];
|
||||||
|
values.forEach(function(x) {
|
||||||
|
values.forEach(function(y) {
|
||||||
|
values.forEach(function(z) {
|
||||||
|
console.log(x && y || z);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -1047,3 +1047,113 @@ issue_2597: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2666: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
return a = {
|
||||||
|
p: function() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
console.log(typeof f().p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
return a = {
|
||||||
|
p: function() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
console.log(typeof f().p());
|
||||||
|
}
|
||||||
|
expect_stdout: "object"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2692: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
reduce_vars: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
return a = g;
|
||||||
|
function g() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(typeof f()());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
return a = g;
|
||||||
|
function g() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(typeof f()());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2701: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
inline: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
return a = function() {
|
||||||
|
return function() {
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
console.log(typeof f()());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
return a = function() {
|
||||||
|
return function() {
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
console.log(typeof f()());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2749: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
inline: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 2, c = "PASS";
|
||||||
|
while (a--)
|
||||||
|
(function() {
|
||||||
|
return b ? c = "FAIL" : b = 1;
|
||||||
|
try {
|
||||||
|
} catch (b) {
|
||||||
|
var b;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 2, c = "PASS";
|
||||||
|
while (a--)
|
||||||
|
b = void 0, b ? c = "FAIL" : b = 1;
|
||||||
|
var b;
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ unused_block_decls: {
|
|||||||
input: {
|
input: {
|
||||||
function foo() {
|
function foo() {
|
||||||
{
|
{
|
||||||
const x;
|
const x = 1;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let y;
|
let y;
|
||||||
@@ -1237,6 +1237,7 @@ var_catch_toplevel: {
|
|||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
|
passes: 2,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -1786,3 +1787,282 @@ issue_2418_5: {
|
|||||||
(function f() {});
|
(function f() {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defun_lambda_same_name: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(n) {
|
||||||
|
return n ? n * f(n - 1) : 1;
|
||||||
|
}
|
||||||
|
console.log(function f(n) {
|
||||||
|
return n ? n * f(n - 1) : 1;
|
||||||
|
}(5));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function f(n) {
|
||||||
|
return n ? n * f(n - 1) : 1;
|
||||||
|
}(5));
|
||||||
|
}
|
||||||
|
expect_stdout: "120"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2660_1: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 2;
|
||||||
|
function f(b) {
|
||||||
|
return b && f() || a--;
|
||||||
|
}
|
||||||
|
f(1);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 2;
|
||||||
|
(function f(b) {
|
||||||
|
return b && f() || a--;
|
||||||
|
})(1);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2660_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
function f(b) {
|
||||||
|
b && f();
|
||||||
|
--a, a.toString();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
(function f(b) {
|
||||||
|
b && f(),
|
||||||
|
(--a).toString();
|
||||||
|
})(),
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2665: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
passes: 2,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
function g() {
|
||||||
|
a-- && g();
|
||||||
|
}
|
||||||
|
typeof h == "function" && h();
|
||||||
|
function h() {
|
||||||
|
typeof g == "function" && g();
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
!function g() {
|
||||||
|
a-- && g();
|
||||||
|
}();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "-1"
|
||||||
|
}
|
||||||
|
|
||||||
|
double_assign_1: {
|
||||||
|
options = {
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1() {
|
||||||
|
var a = {};
|
||||||
|
var a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f2() {
|
||||||
|
var a = {};
|
||||||
|
a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f3() {
|
||||||
|
a = {};
|
||||||
|
var a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f4(a) {
|
||||||
|
a = {};
|
||||||
|
a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f5(a) {
|
||||||
|
var a = {};
|
||||||
|
a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f6(a) {
|
||||||
|
a = {};
|
||||||
|
var a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f1(), f2(), f3(), f4(), f5(), f6());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
function f2() {
|
||||||
|
var a;
|
||||||
|
a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f3() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
function f4(a) {
|
||||||
|
a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f5(a) {
|
||||||
|
a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f6(a) {
|
||||||
|
a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f1(), f2(), f3(), f4(), f5(), f6());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
double_assign_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (var i = 0; i < 2; i++)
|
||||||
|
a = void 0, a = {}, console.log(a);
|
||||||
|
var a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var i = 0; i < 2; i++)
|
||||||
|
void 0, a = {}, console.log(a);
|
||||||
|
var a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double_assign_3: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (var i = 0; i < 2; i++)
|
||||||
|
a = void 0, a = { a: a }, console.log(a);
|
||||||
|
var a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var i = 0; i < 2; i++)
|
||||||
|
a = void 0, a = { a: a }, console.log(a);
|
||||||
|
var a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cascade_drop_assign: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a, b = a = "PASS";
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b = "PASS";
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
chained_3: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, b) {
|
||||||
|
var c = a, c = b;
|
||||||
|
b++;
|
||||||
|
return c;
|
||||||
|
}(1, 2));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a, b) {
|
||||||
|
var c = b;
|
||||||
|
b++;
|
||||||
|
return c;
|
||||||
|
}(0, 2));
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2768: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL", c = 1;
|
||||||
|
var c = function(b) {
|
||||||
|
var d = b = a;
|
||||||
|
var e = --b + (d && (a = "PASS"));
|
||||||
|
}();
|
||||||
|
console.log(a, typeof c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL";
|
||||||
|
var c = (d = a, 0, void (d && (a = "PASS")));
|
||||||
|
var d;
|
||||||
|
console.log(a, typeof c);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS undefined"
|
||||||
|
}
|
||||||
|
|||||||
@@ -800,12 +800,12 @@ issue_2601_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
var a = "FAIL";
|
var a = "FAIL";
|
||||||
(function() {
|
(function() {
|
||||||
|
var b;
|
||||||
b = "foo",
|
b = "foo",
|
||||||
function(b) {
|
function(b) {
|
||||||
b && b();
|
b && b();
|
||||||
}(),
|
}(),
|
||||||
b && (a = "PASS");
|
b && (a = "PASS");
|
||||||
var b;
|
|
||||||
})(),
|
})(),
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
@@ -1318,7 +1318,7 @@ issue_2630_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
var c = 0;
|
var c = 0;
|
||||||
(function() {
|
(function() {
|
||||||
while (c++, void (c = 1 + c));
|
while (void (c = 1 + ++c));
|
||||||
})(),
|
})(),
|
||||||
console.log(c);
|
console.log(c);
|
||||||
}
|
}
|
||||||
@@ -1332,6 +1332,7 @@ issue_2630_2: {
|
|||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1349,7 +1350,7 @@ issue_2630_2: {
|
|||||||
expect: {
|
expect: {
|
||||||
var c = 0;
|
var c = 0;
|
||||||
!function() {
|
!function() {
|
||||||
while (c += 1, void (c = 1 + c));
|
while (void (c = 1 + (c += 1)));
|
||||||
}(), console.log(c);
|
}(), console.log(c);
|
||||||
}
|
}
|
||||||
expect_stdout: "2"
|
expect_stdout: "2"
|
||||||
@@ -1378,11 +1379,10 @@ issue_2630_3: {
|
|||||||
expect: {
|
expect: {
|
||||||
var x = 2, a = 1;
|
var x = 2, a = 1;
|
||||||
(function() {
|
(function() {
|
||||||
function f1(a) {
|
(function f1(a) {
|
||||||
f2();
|
f2();
|
||||||
--x >= 0 && f1({});
|
--x >= 0 && f1({});
|
||||||
}
|
})(a++);
|
||||||
f1(a++);
|
|
||||||
function f2() {
|
function f2() {
|
||||||
a++;
|
a++;
|
||||||
}
|
}
|
||||||
@@ -1450,7 +1450,7 @@ issue_2630_5: {
|
|||||||
!function() {
|
!function() {
|
||||||
do {
|
do {
|
||||||
c *= 10;
|
c *= 10;
|
||||||
} while (c += 3, (c = 2 + c) < 100);
|
} while ((c = 2 + (c += 3)) < 100);
|
||||||
}();
|
}();
|
||||||
console.log(c);
|
console.log(c);
|
||||||
}
|
}
|
||||||
@@ -1516,7 +1516,8 @@ issue_2647_2: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(function() {
|
(function() {
|
||||||
console.log("pass".toUpperCase());
|
console.log((() => (x = "pass", x.toUpperCase()))());
|
||||||
|
var x;
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -1549,7 +1550,7 @@ issue_2647_3: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
recursive_inline: {
|
recursive_inline_1: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
@@ -1572,3 +1573,547 @@ recursive_inline: {
|
|||||||
}
|
}
|
||||||
expect: {}
|
expect: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recursive_inline_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(n) {
|
||||||
|
return n ? n * f(n - 1) : 1;
|
||||||
|
}
|
||||||
|
console.log(f(5));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function f(n) {
|
||||||
|
return n ? n * f(n - 1) : 1;
|
||||||
|
}(5));
|
||||||
|
}
|
||||||
|
expect_stdout: "120"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2657: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
console.log(function f() {
|
||||||
|
return h;
|
||||||
|
function g(b) {
|
||||||
|
return b || b();
|
||||||
|
}
|
||||||
|
function h(a) {
|
||||||
|
g(a);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}()(42));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
console.log(function(a) {
|
||||||
|
return b = a, b || b(), a;
|
||||||
|
var b;
|
||||||
|
}(42));
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2663_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var i, o = {};
|
||||||
|
function createFn(j) {
|
||||||
|
return function() {
|
||||||
|
console.log(j);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
for (i in { a: 1, b: 2, c: 3 })
|
||||||
|
o[i] = createFn(i);
|
||||||
|
for (i in o)
|
||||||
|
o[i]();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
var i, o = {};
|
||||||
|
function createFn(j) {
|
||||||
|
return function() {
|
||||||
|
console.log(j);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
for (i in { a: 1, b: 2, c: 3 })
|
||||||
|
o[i] = createFn(i);
|
||||||
|
for (i in o)
|
||||||
|
o[i]();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"a",
|
||||||
|
"b",
|
||||||
|
"c",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2663_2: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var i;
|
||||||
|
function fn(j) {
|
||||||
|
return function() {
|
||||||
|
console.log(j);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
for (i in { a: 1, b: 2, c: 3 })
|
||||||
|
fn(i);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
var i;
|
||||||
|
for (i in { a: 1, b: 2, c: 3 })
|
||||||
|
j = i, console.log(j);
|
||||||
|
var j;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"a",
|
||||||
|
"b",
|
||||||
|
"c",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2663_3: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function () {
|
||||||
|
var outputs = [
|
||||||
|
{ type: 0, target: null, eventName: "ngSubmit", propName: null },
|
||||||
|
{ type: 0, target: null, eventName: "submit", propName: null },
|
||||||
|
{ type: 0, target: null, eventName: "reset", propName: null },
|
||||||
|
];
|
||||||
|
function listenToElementOutputs(outputs) {
|
||||||
|
var handlers = [];
|
||||||
|
for (var i = 0; i < outputs.length; i++) {
|
||||||
|
var output = outputs[i];
|
||||||
|
var handleEventClosure = renderEventHandlerClosure(output.eventName);
|
||||||
|
handlers.push(handleEventClosure)
|
||||||
|
}
|
||||||
|
var target, name;
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
function renderEventHandlerClosure(eventName) {
|
||||||
|
return function () {
|
||||||
|
return console.log(eventName);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
listenToElementOutputs(outputs).forEach(function (handler) {
|
||||||
|
return handler()
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
function renderEventHandlerClosure(eventName) {
|
||||||
|
return function() {
|
||||||
|
return console.log(eventName);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
(function(outputs) {
|
||||||
|
var handlers = [];
|
||||||
|
for (var i = 0; i < outputs.length; i++) {
|
||||||
|
var output = outputs[i];
|
||||||
|
var handleEventClosure = renderEventHandlerClosure(output.eventName);
|
||||||
|
handlers.push(handleEventClosure);
|
||||||
|
}
|
||||||
|
return handlers;
|
||||||
|
})([ {
|
||||||
|
type: 0,
|
||||||
|
target: null,
|
||||||
|
eventName: "ngSubmit",
|
||||||
|
propName: null
|
||||||
|
}, {
|
||||||
|
type: 0,
|
||||||
|
target: null,
|
||||||
|
eventName: "submit",
|
||||||
|
propName: null
|
||||||
|
}, {
|
||||||
|
type: 0,
|
||||||
|
target: null,
|
||||||
|
eventName: "reset",
|
||||||
|
propName: null
|
||||||
|
} ]).forEach(function(handler) {
|
||||||
|
return handler();
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"ngSubmit",
|
||||||
|
"submit",
|
||||||
|
"reset",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_argnames: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
function f(b, b, b) {
|
||||||
|
b && (a = "FAIL");
|
||||||
|
}
|
||||||
|
f(0, console);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
console, b && (a = "FAIL");
|
||||||
|
var b;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
loop_init_arg: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
for (var k in "12") (function (b) {
|
||||||
|
(b >>= 1) && (a = "FAIL"), b = 2;
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
for (var k in "12")
|
||||||
|
b = void 0, (b >>= 1) && (a = "FAIL"), b = 2;
|
||||||
|
var b;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_false: {
|
||||||
|
options = {
|
||||||
|
inline: false,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_0: {
|
||||||
|
options = {
|
||||||
|
inline: 0,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_1: {
|
||||||
|
options = {
|
||||||
|
inline: 1,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1);
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_2: {
|
||||||
|
options = {
|
||||||
|
inline: 2,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1);
|
||||||
|
a = 2, console.log(a);
|
||||||
|
var a;
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_3: {
|
||||||
|
options = {
|
||||||
|
inline: 3,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1);
|
||||||
|
a = 2, console.log(a);
|
||||||
|
var a;
|
||||||
|
b = 3, c = b, console.log(c);
|
||||||
|
var b, c;
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_true: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1);
|
||||||
|
a = 2, console.log(a);
|
||||||
|
var a;
|
||||||
|
b = 3, c = b, console.log(c);
|
||||||
|
var b, c;
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
use_before_init_in_loop: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
for (var b = 2; --b >= 0;) (function() {
|
||||||
|
var c = function() {
|
||||||
|
return 1;
|
||||||
|
}(c && (a = "FAIL"));
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
for (var b = 2; --b >= 0;)
|
||||||
|
c = void 0, c = (c && (a = "FAIL"), 1);
|
||||||
|
var c;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_arg_var: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(b) {
|
||||||
|
return b;
|
||||||
|
var b;
|
||||||
|
}("PASS"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log((b = "PASS", b));
|
||||||
|
var b;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2737_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
while (a());
|
||||||
|
})(function f() {
|
||||||
|
console.log(typeof f);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
while (a());
|
||||||
|
})(function f() {
|
||||||
|
console.log(typeof f);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2737_2: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(bar) {
|
||||||
|
for (;bar(); ) break;
|
||||||
|
})(function qux() {
|
||||||
|
return console.log("PASS"), qux;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(bar) {
|
||||||
|
for (;bar(); ) break;
|
||||||
|
})(function qux() {
|
||||||
|
return console.log("PASS"), qux;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1197,3 +1197,51 @@ class_method_using_arguments: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2676: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
class A {}
|
||||||
|
A.a = 42;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(class {}).a = 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2762: {
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
var bar = 1, T = true;
|
||||||
|
(function() {
|
||||||
|
if (T) {
|
||||||
|
const a = function() {
|
||||||
|
var foo = bar;
|
||||||
|
console.log(foo, a.prop, b.prop);
|
||||||
|
};
|
||||||
|
a.prop = 2;
|
||||||
|
const b = { prop: 3 };
|
||||||
|
a();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var bar = 1, T = true;
|
||||||
|
(function() {
|
||||||
|
if (T) {
|
||||||
|
const o = function() {
|
||||||
|
var p = bar;
|
||||||
|
console.log(p, o.prop, r.prop);
|
||||||
|
};
|
||||||
|
o.prop = 2;
|
||||||
|
const r = { prop: 3 };
|
||||||
|
o();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "1 2 3"
|
||||||
|
}
|
||||||
|
|||||||
@@ -827,3 +827,73 @@ issue_2519: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "5.5"
|
expect_stdout: "5.5"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toplevel_const: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const a = {
|
||||||
|
b: 1,
|
||||||
|
c: 2
|
||||||
|
};
|
||||||
|
console.log(a.b + a.c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const a = {
|
||||||
|
b: 1,
|
||||||
|
c: 2
|
||||||
|
};
|
||||||
|
console.log(a.b + a.c);
|
||||||
|
}
|
||||||
|
expect_stdout: "3"
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_let: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
let a = {
|
||||||
|
b: 1,
|
||||||
|
c: 2
|
||||||
|
};
|
||||||
|
console.log(a.b + a.c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
let a = {
|
||||||
|
b: 1,
|
||||||
|
c: 2
|
||||||
|
};
|
||||||
|
console.log(a.b + a.c);
|
||||||
|
}
|
||||||
|
expect_stdout: "3"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_var: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = {
|
||||||
|
b: 1,
|
||||||
|
c: 2
|
||||||
|
};
|
||||||
|
console.log(a.b + a.c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = {
|
||||||
|
b: 1,
|
||||||
|
c: 2
|
||||||
|
};
|
||||||
|
console.log(a.b + a.c);
|
||||||
|
}
|
||||||
|
expect_stdout: "3"
|
||||||
|
}
|
||||||
|
|||||||
@@ -384,3 +384,109 @@ issue_1317_strict: {
|
|||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if_var_return: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var a;
|
||||||
|
return;
|
||||||
|
var b;
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
var a;
|
||||||
|
if (u()) {
|
||||||
|
var b;
|
||||||
|
return v();
|
||||||
|
var c;
|
||||||
|
}
|
||||||
|
var d;
|
||||||
|
if (w()) {
|
||||||
|
var e;
|
||||||
|
return x();
|
||||||
|
var f;
|
||||||
|
} else {
|
||||||
|
var g;
|
||||||
|
y();
|
||||||
|
var h;
|
||||||
|
}
|
||||||
|
var i;
|
||||||
|
z();
|
||||||
|
var j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
var a, b;
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
var a, b, c, d, e, f, g, h, i, j;
|
||||||
|
return u() ? v() : w() ? x() : (y(), z(), void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if_if_return_return: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, b) {
|
||||||
|
if (a) {
|
||||||
|
if (b)
|
||||||
|
return b;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, b) {
|
||||||
|
if (a)
|
||||||
|
return b || void 0;
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2747: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
sequences: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
function f(baz) {
|
||||||
|
if (baz === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let r;
|
||||||
|
if (baz > 2) {
|
||||||
|
r = 4;
|
||||||
|
} else {
|
||||||
|
r = 5;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
console.log(f(0), f(1), f(3));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
function f(baz) {
|
||||||
|
if (0 === baz) return null;
|
||||||
|
let r;
|
||||||
|
return r = baz > 2 ? 4 : 5, r;
|
||||||
|
}
|
||||||
|
console.log(f(0), f(1), f(3));
|
||||||
|
}
|
||||||
|
expect_stdout: "null 5 4"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -64,3 +64,27 @@ strings_concat: {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
regexp: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
RegExp("foo");
|
||||||
|
RegExp("bar", "ig");
|
||||||
|
RegExp(foo);
|
||||||
|
RegExp("bar", ig);
|
||||||
|
RegExp("should", "fail");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
/foo/;
|
||||||
|
/bar/ig;
|
||||||
|
RegExp(foo);
|
||||||
|
RegExp("bar", ig);
|
||||||
|
RegExp("should", "fail");
|
||||||
|
}
|
||||||
|
expect_warnings: [
|
||||||
|
'WARN: Error converting RegExp("should","fail") [test/compress/issue-269.js:78,2]',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
32
test/compress/issue-2719.js
Normal file
32
test/compress/issue-2719.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
warn: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
properties: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
return g();
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
return g["call" + "er"].arguments;
|
||||||
|
}
|
||||||
|
// 3
|
||||||
|
console.log(f(1, 2, 3).length);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
// TypeError: Cannot read property 'arguments' of null
|
||||||
|
console.log(function g() {
|
||||||
|
return g.caller.arguments;
|
||||||
|
}().length);
|
||||||
|
}
|
||||||
|
expect_warnings: [
|
||||||
|
"WARN: Function.protoype.caller not supported [test/compress/issue-2719.js:17,19]",
|
||||||
|
"WARN: Function.protoype.arguments not supported [test/compress/issue-2719.js:17,19]",
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -536,3 +536,182 @@ dead_code_condition: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2740_1: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (; ; ) break;
|
||||||
|
for (a(); ; ) break;
|
||||||
|
for (; b(); ) break;
|
||||||
|
for (c(); d(); ) break;
|
||||||
|
for (; ; e()) break;
|
||||||
|
for (f(); ; g()) break;
|
||||||
|
for (; h(); i()) break;
|
||||||
|
for (j(); k(); l()) break;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a();
|
||||||
|
b();
|
||||||
|
c();
|
||||||
|
d();
|
||||||
|
f();
|
||||||
|
h();
|
||||||
|
j();
|
||||||
|
k();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_2: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
L1: while (x()) {
|
||||||
|
break L1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
x();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_3: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
L1: for (var x = 0; x < 3; x++) {
|
||||||
|
L2: for (var y = 0; y < 2; y++) {
|
||||||
|
break L1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
L1: for (var x = 0; x < 3; x++)
|
||||||
|
for (var y = 0; y < 2; y++)
|
||||||
|
break L1;
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
expect_stdout: "0 0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_4: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
L1: for (var x = 0; x < 3; x++) {
|
||||||
|
L2: for (var y = 0; y < 2; y++) {
|
||||||
|
break L2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var x = 0; x < 3; x++) {
|
||||||
|
var y = 0;
|
||||||
|
y < 2;
|
||||||
|
}
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
expect_stdout: "3 0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_5: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
L1: for (var x = 0; x < 3; x++) {
|
||||||
|
break L1;
|
||||||
|
L2: for (var y = 0; y < 2; y++) {
|
||||||
|
break L2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var x = 0;
|
||||||
|
x < 3;
|
||||||
|
var y;
|
||||||
|
console.log(x,y);
|
||||||
|
}
|
||||||
|
expect_stdout: "0 undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_6: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const a = 9, b = 0;
|
||||||
|
for (const a = 1; a < 3; ++b) break;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const a = 9, b = 0;
|
||||||
|
{
|
||||||
|
const a = 1;
|
||||||
|
a < 3;
|
||||||
|
}
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "9 0"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_7: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
let a = 9, b = 0;
|
||||||
|
for (const a = 1; a < 3; ++b) break;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
let a = 9, b = 0;
|
||||||
|
{
|
||||||
|
const a = 1;
|
||||||
|
a < 3;
|
||||||
|
}
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "9 0"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_8: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 9, b = 0;
|
||||||
|
for (const a = 1; a < 3; ++b) break;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 9, b = 0;
|
||||||
|
{
|
||||||
|
const a = 1;
|
||||||
|
a < 3;
|
||||||
|
}
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "9 0"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|||||||
@@ -569,12 +569,18 @@ native_prototype: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
Array.prototype.splice.apply(a, [1, 2, b, c]);
|
Array.prototype.splice.apply(a, [1, 2, b, c]);
|
||||||
|
Function.prototype.call.apply(console.log, console, [ "foo" ]);
|
||||||
|
Number.prototype.toFixed.call(Math.PI, 2);
|
||||||
Object.prototype.hasOwnProperty.call(d, "foo");
|
Object.prototype.hasOwnProperty.call(d, "foo");
|
||||||
|
RegExp.prototype.test.call(/foo/, "bar");
|
||||||
String.prototype.indexOf.call(e, "bar");
|
String.prototype.indexOf.call(e, "bar");
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
[].splice.apply(a, [1, 2, b, c]);
|
[].splice.apply(a, [1, 2, b, c]);
|
||||||
|
(function() {}).call.apply(console.log, console, [ "foo" ]);
|
||||||
|
0..toFixed.call(Math.PI, 2);
|
||||||
({}).hasOwnProperty.call(d, "foo");
|
({}).hasOwnProperty.call(d, "foo");
|
||||||
|
/t/.test.call(/foo/, "bar");
|
||||||
"".indexOf.call(e, "bar");
|
"".indexOf.call(e, "bar");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1371,3 +1377,201 @@ const_prop_assign_pure: {
|
|||||||
x();
|
x();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
join_object_assignments_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var x = {
|
||||||
|
a: 1,
|
||||||
|
c: (console.log("c"), "C"),
|
||||||
|
};
|
||||||
|
x.b = 2;
|
||||||
|
x[3] = function() {
|
||||||
|
console.log(x);
|
||||||
|
},
|
||||||
|
x["a"] = /foo/,
|
||||||
|
x.bar = x;
|
||||||
|
return x;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var x = {
|
||||||
|
a: 1,
|
||||||
|
c: (console.log("c"), "C"),
|
||||||
|
b: 2,
|
||||||
|
3: function() {
|
||||||
|
console.log(x);
|
||||||
|
},
|
||||||
|
a: /foo/,
|
||||||
|
};
|
||||||
|
x.bar = x;
|
||||||
|
return x;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
hoist_props: true,
|
||||||
|
join_vars: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
foo: 1,
|
||||||
|
};
|
||||||
|
o.bar = 2;
|
||||||
|
o.baz = 3;
|
||||||
|
console.log(o.foo, o.bar + o.bar, o.foo * o.bar * o.baz);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1, 4, 6);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 4 6"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
a: "PASS",
|
||||||
|
}, a = o.a;
|
||||||
|
o.a = "FAIL";
|
||||||
|
return a;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
a: "PASS",
|
||||||
|
}, a = o.a;
|
||||||
|
o.a = "FAIL";
|
||||||
|
return a;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_4: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
p: 3
|
||||||
|
};
|
||||||
|
return o.q = "foo";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
p: 3,
|
||||||
|
q: "foo"
|
||||||
|
};
|
||||||
|
return o.q;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "foo"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_5: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
p: 3
|
||||||
|
};
|
||||||
|
return o.q = /foo/,
|
||||||
|
o.r = "bar";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
p: 3,
|
||||||
|
q: /foo/,
|
||||||
|
r: "bar"
|
||||||
|
};
|
||||||
|
return o.r;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_6: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
p: 3
|
||||||
|
};
|
||||||
|
return o.q = "foo",
|
||||||
|
o.p += "",
|
||||||
|
console.log(o.q),
|
||||||
|
o.p;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
p: 3,
|
||||||
|
q: "foo"
|
||||||
|
};
|
||||||
|
return o.p += "",
|
||||||
|
console.log(o.q),
|
||||||
|
o.p;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_7: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
p: 3
|
||||||
|
};
|
||||||
|
for (o.q = "foo"; console.log(o.q););
|
||||||
|
return o.p;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
for (var o = {
|
||||||
|
p: 3,
|
||||||
|
q: "foo"
|
||||||
|
}; console.log(o.q););
|
||||||
|
return o.p;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -414,3 +414,124 @@ issue_2638: {
|
|||||||
"/* */(a()||b())(c(),d());",
|
"/* */(a()||b())(c(),d());",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2705_1: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ new a();
|
||||||
|
/*@__PURE__*/ (new b());
|
||||||
|
new (/*@__PURE__*/ c)();
|
||||||
|
(/*@__PURE__*/ new d());
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"new/* */c;",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_2: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ new a(1)(2)(3);
|
||||||
|
/*@__PURE__*/ new (b(1))(2)(3);
|
||||||
|
/*@__PURE__*/ new (c(1)(2))(3);
|
||||||
|
/*@__PURE__*/ new (d(1)(2)(3));
|
||||||
|
new (/*@__PURE__*/ e)(1)(2)(3);
|
||||||
|
(/*@__PURE__*/ new f(1))(2)(3);
|
||||||
|
(/*@__PURE__*/ new g(1)(2))(3);
|
||||||
|
(/*@__PURE__*/ new h(1)(2)(3));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"new/* */e(1)(2)(3);",
|
||||||
|
"/* */new f(1)(2)(3);",
|
||||||
|
"/* */new g(1)(2)(3);",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_3: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ new a.x(1).y(2).z(3);
|
||||||
|
/*@__PURE__*/ new (b.x)(1).y(2).z(3);
|
||||||
|
/*@__PURE__*/ new (c.x(1)).y(2).z(3);
|
||||||
|
/*@__PURE__*/ new (d.x(1).y)(2).z(3);
|
||||||
|
/*@__PURE__*/ new (e.x(1).y(2)).z(3);
|
||||||
|
/*@__PURE__*/ new (f.x(1).y(2).z)(3);
|
||||||
|
/*@__PURE__*/ new (g.x(1).y(2).z(3));
|
||||||
|
new (/*@__PURE__*/ h).x(1).y(2).z(3);
|
||||||
|
/* */ new (/*@__PURE__*/ i.x)(1).y(2).z(3);
|
||||||
|
(/*@__PURE__*/ new j.x(1)).y(2).z(3);
|
||||||
|
(/*@__PURE__*/ new k.x(1).y)(2).z(3);
|
||||||
|
(/*@__PURE__*/ new l.x(1).y(2)).z(3);
|
||||||
|
(/*@__PURE__*/ new m.x(1).y(2).z)(3);
|
||||||
|
(/*@__PURE__*/ new n.x(1).y(2).z(3));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"new/* */h.x(1).y(2).z(3);",
|
||||||
|
"/* */new/* */i.x(1).y(2).z(3);",
|
||||||
|
"/* */new j.x(1).y(2).z(3);",
|
||||||
|
"/* */new k.x(1).y(2).z(3);",
|
||||||
|
"/* */new l.x(1).y(2).z(3);",
|
||||||
|
"/* */new m.x(1).y(2).z(3);",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_4: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(/*@__PURE__*/ new x(), y());
|
||||||
|
(w(), /*@__PURE__*/ new x(), y());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
y();
|
||||||
|
w(), y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_5: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
[ /*@__PURE__*/ new x() ];
|
||||||
|
[ /*@__PURE__*/ new x(), y() ];
|
||||||
|
[ w(), /*@__PURE__*/ new x(), y() ];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
y();
|
||||||
|
w(), y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_6: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/new (g() || h())(x(), y());
|
||||||
|
/* */ new (/*@__PURE__*/ (a() || b()))(c(), d());
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"/* */x(),y();",
|
||||||
|
"/* */new(/* */a()||b())(c(),d());",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -348,6 +348,57 @@ set_immutable_4: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_immutable_5: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
1..foo += "";
|
||||||
|
1..foo ? console.log("FAIL") : console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
set_immutable_6: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
1..foo ? console.log("FAIL") : console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
set_mutable_1: {
|
set_mutable_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -735,3 +786,35 @@ issue_2313_7: {
|
|||||||
expect_stdout: "2 1"
|
expect_stdout: "2 1"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2678: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1, c = "FAIL";
|
||||||
|
(function f() {
|
||||||
|
(a-- && f()).p;
|
||||||
|
return {
|
||||||
|
get p() {
|
||||||
|
c = "PASS";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1, c = "FAIL";
|
||||||
|
(function f() {
|
||||||
|
(a-- && f()).p;
|
||||||
|
return {
|
||||||
|
get p() {
|
||||||
|
c = "PASS";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ unsafe_evaluate_modified: {
|
|||||||
console.log(function(){ var o={p:1}; o.p++; console.log(o.p); return o.p; }());
|
console.log(function(){ var o={p:1}; o.p++; console.log(o.p); return o.p; }());
|
||||||
console.log(function(){ var o={p:2}; --o.p; console.log(o.p); return o.p; }());
|
console.log(function(){ var o={p:2}; --o.p; console.log(o.p); return o.p; }());
|
||||||
console.log(function(){ var o={p:3}; o.p += ""; console.log(o.p); return o.p; }());
|
console.log(function(){ var o={p:3}; o.p += ""; console.log(o.p); return o.p; }());
|
||||||
console.log(function(){ var o={p:4}; o = {}; console.log(o.p); return o.p; }());
|
console.log(function(){ var o; o = {}; console.log(o.p); return o.p; }());
|
||||||
console.log(function(){ var o={p:5}; o.p = -9; console.log(o.p); return o.p; }());
|
console.log(function(){ var o={p:5}; o.p = -9; console.log(o.p); return o.p; }());
|
||||||
function inc() { this.p++; }
|
function inc() { this.p++; }
|
||||||
console.log(function(){ var o={p:6}; inc.call(o); console.log(o.p); return o.p; }());
|
console.log(function(){ var o={p:6}; inc.call(o); console.log(o.p); return o.p; }());
|
||||||
@@ -1355,10 +1355,9 @@ defun_inline_1: {
|
|||||||
function f() {
|
function f() {
|
||||||
return function(b) {
|
return function(b) {
|
||||||
return b;
|
return b;
|
||||||
}(2) + h();
|
}(2) + function h() {
|
||||||
function h() {
|
|
||||||
return h();
|
return h();
|
||||||
}
|
}();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1382,12 +1381,11 @@ defun_inline_2: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f() {
|
function f() {
|
||||||
function h() {
|
|
||||||
return h();
|
|
||||||
}
|
|
||||||
return function(b) {
|
return function(b) {
|
||||||
return b;
|
return b;
|
||||||
}(2) + h();
|
}(2) + function h() {
|
||||||
|
return h();
|
||||||
|
}();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1557,10 +1555,10 @@ defun_label: {
|
|||||||
!function() {
|
!function() {
|
||||||
console.log(function(a) {
|
console.log(function(a) {
|
||||||
L: {
|
L: {
|
||||||
if (a) break L;
|
if (2) break L;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}(2));
|
}());
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -2314,8 +2312,7 @@ delay_def: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f() {
|
function f() {
|
||||||
return a;
|
return;
|
||||||
var a;
|
|
||||||
}
|
}
|
||||||
function g() {
|
function g() {
|
||||||
return a;
|
return a;
|
||||||
@@ -2326,6 +2323,28 @@ delay_def: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delay_def_lhs: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
long_name++;
|
||||||
|
return long_name;
|
||||||
|
var long_name;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
long_name++;
|
||||||
|
return long_name;
|
||||||
|
var long_name;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "NaN"
|
||||||
|
}
|
||||||
|
|
||||||
booleans: {
|
booleans: {
|
||||||
options = {
|
options = {
|
||||||
booleans: true,
|
booleans: true,
|
||||||
@@ -3368,9 +3387,7 @@ obj_for_1: {
|
|||||||
console.log(i);
|
console.log(i);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
// TODO make this work on harmony
|
for (var i = { a: 1 }.a--; i; i--)
|
||||||
var o = { a: 1 };
|
|
||||||
for (var i = o.a--; i; i--)
|
|
||||||
console.log(i);
|
console.log(i);
|
||||||
}
|
}
|
||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
@@ -3409,9 +3426,7 @@ array_forin_1: {
|
|||||||
console.log(b);
|
console.log(b);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
// TODO make this work on harmony
|
for (var b in [ 1, 2, 3 ])
|
||||||
var a = [ 1, 2, 3 ];
|
|
||||||
for (var b in a)
|
|
||||||
console.log(b);
|
console.log(b);
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
@@ -3456,9 +3471,7 @@ array_forof_1: {
|
|||||||
console.log(b);
|
console.log(b);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
// TODO make this work on harmony
|
for (var b of [ 1, 2, 3 ])
|
||||||
var a = [ 1, 2, 3 ];
|
|
||||||
for (var b of a)
|
|
||||||
console.log(b);
|
console.log(b);
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
@@ -5162,10 +5175,8 @@ escape_local_throw: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function baz() {
|
function baz() {
|
||||||
// TODO: improve to match `master`
|
|
||||||
function foo() {}
|
|
||||||
try {
|
try {
|
||||||
throw foo;
|
throw function() {};
|
||||||
} catch (bar) {
|
} catch (bar) {
|
||||||
return bar;
|
return bar;
|
||||||
}
|
}
|
||||||
@@ -5446,3 +5457,438 @@ issue_2598: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "true"
|
expect_stdout: "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2669: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
let foo;
|
||||||
|
console.log(([ foo ] = [ "PASS" ]) && foo);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
let foo;
|
||||||
|
console.log(([ foo ] = [ "PASS" ]) && foo);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2670: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const obj = {};
|
||||||
|
obj.prop = "PASS";
|
||||||
|
const {prop: value} = obj;
|
||||||
|
console.log(value);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const obj = {};
|
||||||
|
obj.prop = "PASS";
|
||||||
|
const {prop: value} = obj;
|
||||||
|
console.log(value);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
var_if: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
if (x()) {
|
||||||
|
var a;
|
||||||
|
if (!g) a = true;
|
||||||
|
if (a) g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
if (x()) {
|
||||||
|
var a;
|
||||||
|
if (!g) a = true;
|
||||||
|
if (a) g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_assign: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof a);
|
||||||
|
a = 42;
|
||||||
|
console.log(typeof a);
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof a);
|
||||||
|
a = 42;
|
||||||
|
console.log(typeof a);
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"function",
|
||||||
|
"number",
|
||||||
|
"number",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_var_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 42, b;
|
||||||
|
function a() {}
|
||||||
|
function b() {}
|
||||||
|
console.log(typeof a, typeof b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 42;
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a, "function");
|
||||||
|
}
|
||||||
|
expect_stdout: "number function"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_var_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a() {}
|
||||||
|
function b() {}
|
||||||
|
var a = 42, b;
|
||||||
|
console.log(typeof a, typeof b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a() {}
|
||||||
|
var a = 42;
|
||||||
|
console.log(typeof a, "function");
|
||||||
|
}
|
||||||
|
expect_stdout: "number function"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_var_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a() {}
|
||||||
|
function b() {}
|
||||||
|
console.log(typeof a, typeof b);
|
||||||
|
var a = 42, b;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a, "function");
|
||||||
|
var a = 42;
|
||||||
|
}
|
||||||
|
expect_stdout: "function function"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_1: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a() {}
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
// TODO: drop unused AST_Defun
|
||||||
|
function a() {}
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
function a() {}
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
// TODO: drop unused AST_Defun
|
||||||
|
function a() {}
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_3: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
function a() {}
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
// TODO: drop unused AST_Defun
|
||||||
|
function a() {}
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_4: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
function a() {}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
function a() {}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_5: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
function a() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
function a() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_6: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
function a() {}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
// TODO: drop unused AST_Defun
|
||||||
|
function a() {}
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_lambda_defun_name_1: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function f(a) {
|
||||||
|
function f() {}
|
||||||
|
return f.length;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function f(a) {
|
||||||
|
function f() {}
|
||||||
|
return f.length;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_lambda_defun_name_2: {
|
||||||
|
options = {
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function f(a) {
|
||||||
|
function f() {}
|
||||||
|
return f.length;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return function() {}.length;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2757_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
let u;
|
||||||
|
(function() {
|
||||||
|
let v;
|
||||||
|
console.log(u, v);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
let u;
|
||||||
|
console.log(u, void 0);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined undefined"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2757_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
let bar;
|
||||||
|
const unused = function() {
|
||||||
|
bar = true;
|
||||||
|
};
|
||||||
|
if (!bar) {
|
||||||
|
console.log(1);
|
||||||
|
}
|
||||||
|
console.log(2);
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1),
|
||||||
|
console.log(2);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2774: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
get a() {
|
||||||
|
var b;
|
||||||
|
(b = true) && b.c;
|
||||||
|
b = void 0;
|
||||||
|
}
|
||||||
|
}.a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
get a() {
|
||||||
|
var b;
|
||||||
|
(b = true) && b.c;
|
||||||
|
b = void 0;
|
||||||
|
}
|
||||||
|
}.a);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|||||||
@@ -820,3 +820,66 @@ cascade_assignment_in_return: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hoist_defun: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
x();
|
||||||
|
function f() {}
|
||||||
|
y();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {}
|
||||||
|
x(), y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hoist_decl: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
w();
|
||||||
|
var b = x();
|
||||||
|
y();
|
||||||
|
for (var c; 0;) z();
|
||||||
|
var d;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
w();
|
||||||
|
var b = x(), c, d;
|
||||||
|
for (y(); 0;) z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for_init_var: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
unused: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function() {
|
||||||
|
var b = 42;
|
||||||
|
for (var c = 5; c > 0;) c--;
|
||||||
|
a = "FAIL";
|
||||||
|
var a;
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function() {
|
||||||
|
for (var b = 42, c = 5, a; c > 0;) c--;
|
||||||
|
a = "FAIL";
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ typeof_defun_1: {
|
|||||||
g = 42;
|
g = 42;
|
||||||
console.log("YES");
|
console.log("YES");
|
||||||
"function" == typeof g && g();
|
"function" == typeof g && g();
|
||||||
h();
|
"function" == typeof h && h();
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"YES",
|
"YES",
|
||||||
@@ -138,3 +138,166 @@ typeof_defun_2: {
|
|||||||
"2",
|
"2",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
duplicate_defun_arg_name: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function long_name(long_name) {
|
||||||
|
return typeof long_name;
|
||||||
|
}
|
||||||
|
console.log(typeof long_name, long_name());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function long_name(long_name) {
|
||||||
|
return typeof long_name;
|
||||||
|
}
|
||||||
|
console.log(typeof long_name, long_name());
|
||||||
|
}
|
||||||
|
expect_stdout: "function undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_lambda_arg_name: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function long_name(long_name) {
|
||||||
|
return typeof long_name;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function long_name(long_name) {
|
||||||
|
return typeof long_name;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function arguments() {
|
||||||
|
console.log(typeof arguments);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function arguments() {
|
||||||
|
console.log(typeof arguments);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "object"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function arguments() {
|
||||||
|
return typeof arguments;
|
||||||
|
}
|
||||||
|
console.log(typeof arguments, arguments());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function arguments() {
|
||||||
|
return typeof arguments;
|
||||||
|
}
|
||||||
|
console.log(typeof arguments, arguments());
|
||||||
|
}
|
||||||
|
expect_stdout: "function object"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
function arguments() {
|
||||||
|
}
|
||||||
|
console.log(typeof arguments);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
function arguments() {
|
||||||
|
}
|
||||||
|
console.log("function");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_4: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function arguments() {
|
||||||
|
}
|
||||||
|
console.log(typeof arguments);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function arguments() {
|
||||||
|
}
|
||||||
|
console.log("function");
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_5: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function arguments(arguments) {
|
||||||
|
console.log(typeof arguments);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function arguments(arguments) {
|
||||||
|
console.log(typeof arguments);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_6: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function arguments(arguments) {
|
||||||
|
return typeof arguments;
|
||||||
|
}
|
||||||
|
console.log(typeof arguments, arguments());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function arguments(arguments) {
|
||||||
|
return typeof arguments;
|
||||||
|
}
|
||||||
|
console.log(typeof arguments, arguments());
|
||||||
|
}
|
||||||
|
expect_stdout: "function undefined"
|
||||||
|
}
|
||||||
|
|||||||
@@ -88,9 +88,8 @@ yield_before_punctuators: {
|
|||||||
})();
|
})();
|
||||||
function* g1() { (yield) }
|
function* g1() { (yield) }
|
||||||
function* g2() { [yield] }
|
function* g2() { [yield] }
|
||||||
function* g3() { return {yield} } // Added return to avoid {} drop
|
function* g3() { yield, yield; }
|
||||||
function* g4() { yield, yield; }
|
function* g4() { (yield) ? yield : yield; }
|
||||||
function* g5() { (yield) ? yield : yield; }
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
iter = (function*() {
|
iter = (function*() {
|
||||||
@@ -98,9 +97,8 @@ yield_before_punctuators: {
|
|||||||
})();
|
})();
|
||||||
function* g1() { (yield) }
|
function* g1() { (yield) }
|
||||||
function* g2() { [yield] }
|
function* g2() { [yield] }
|
||||||
function* g3() { return {yield} }
|
function* g3() { yield, yield; }
|
||||||
function* g4() { yield, yield; }
|
function* g4() { (yield) ? yield : yield; }
|
||||||
function* g5() { (yield) ? yield : yield; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,3 +197,17 @@ yield_as_ES5_property: {
|
|||||||
expect_exact: '"use strict";console.log({yield:42}.yield);'
|
expect_exact: '"use strict";console.log({yield:42}.yield);'
|
||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2689: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function* y() {
|
||||||
|
var t = yield x();
|
||||||
|
return new t();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "function*y(){return new(yield x())}"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
function f() {
|
function f() {
|
||||||
const a;
|
const a;
|
||||||
}
|
}
|
||||||
|
|
||||||
function g() {
|
|
||||||
"use strict";
|
|
||||||
const a;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var a = bar(1+2);
|
var x = bar(1+2);
|
||||||
var b = baz(3+9);
|
var y = baz(3+9);
|
||||||
print('q' + 'u' + 'x', a, b);
|
print('q' + 'u' + 'x', x, y);
|
||||||
foo(5+6);
|
foo(5+6);
|
||||||
|
|||||||
@@ -5,11 +5,7 @@
|
|||||||
|
|
||||||
var site = "http://browserbench.org/JetStream";
|
var site = "http://browserbench.org/JetStream";
|
||||||
if (typeof phantom == "undefined") {
|
if (typeof phantom == "undefined") {
|
||||||
// workaround for tty output truncation upon process.exit()
|
require("../tools/exit");
|
||||||
[process.stdout, process.stderr].forEach(function(stream){
|
|
||||||
if (stream._handle && stream._handle.setBlocking)
|
|
||||||
stream._handle.setBlocking(true);
|
|
||||||
});
|
|
||||||
var args = process.argv.slice(2);
|
var args = process.argv.slice(2);
|
||||||
var debug = args.indexOf("--debug");
|
var debug = args.indexOf("--debug");
|
||||||
if (debug >= 0) {
|
if (debug >= 0) {
|
||||||
|
|||||||
@@ -408,7 +408,7 @@ describe("bin/uglifyjs", function () {
|
|||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/const.js:7,11",
|
"Parse error at test/input/invalid/const.js:2,11",
|
||||||
" const a;",
|
" const a;",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Missing initializer in const declaration"
|
"ERROR: Missing initializer in const declaration"
|
||||||
|
|||||||
@@ -220,4 +220,24 @@ describe("Comment", function() {
|
|||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code, "/*a*/ /*b*/(function(){/*c*/}/*d*/ /*e*/)();");
|
assert.strictEqual(result.code, "/*a*/ /*b*/(function(){/*c*/}/*d*/ /*e*/)();");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should output line comments after statements", function() {
|
||||||
|
var result = uglify.minify([
|
||||||
|
"x()//foo",
|
||||||
|
"{y()//bar",
|
||||||
|
"}",
|
||||||
|
].join("\n"), {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
comments: "all",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, [
|
||||||
|
"x();//foo",
|
||||||
|
"{y();//bar",
|
||||||
|
"}",
|
||||||
|
].join("\n"));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -42,8 +42,15 @@ describe("minify", function() {
|
|||||||
original += code;
|
original += code;
|
||||||
compressed += result.code;
|
compressed += result.code;
|
||||||
});
|
});
|
||||||
assert.strictEqual(JSON.stringify(cache).slice(0, 20), '{"cname":5,"props":{');
|
assert.strictEqual(JSON.stringify(cache).slice(0, 10), '{"props":{');
|
||||||
assert.strictEqual(compressed, 'function n(n){return 3*n}function r(n){return n/2}var c=console.log.bind(console);function l(o){c("Foo:",2*o)}var f=n(3),i=r(12);c("qux",f,i),l(11);');
|
assert.strictEqual(compressed, [
|
||||||
|
"function n(n){return 3*n}",
|
||||||
|
"function r(n){return n/2}",
|
||||||
|
"var o=console.log.bind(console);",
|
||||||
|
'function c(n){o("Foo:",2*n)}',
|
||||||
|
"var a=n(3),b=r(12);",
|
||||||
|
'o("qux",a,b),c(11);',
|
||||||
|
].join(""));
|
||||||
assert.strictEqual(run_code(compressed), run_code(original));
|
assert.strictEqual(run_code(compressed), run_code(original));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -68,12 +75,48 @@ describe("minify", function() {
|
|||||||
original += code;
|
original += code;
|
||||||
compressed += result.code;
|
compressed += result.code;
|
||||||
});
|
});
|
||||||
assert.strictEqual(JSON.stringify(cache).slice(0, 28), '{"vars":{"cname":5,"props":{');
|
assert.strictEqual(JSON.stringify(cache).slice(0, 18), '{"vars":{"props":{');
|
||||||
assert.strictEqual(compressed, 'function n(n){return 3*n}function r(n){return n/2}var c=console.log.bind(console);function l(o){c("Foo:",2*o)}var f=n(3),i=r(12);c("qux",f,i),l(11);');
|
assert.strictEqual(compressed, [
|
||||||
|
"function n(n){return 3*n}",
|
||||||
|
"function r(n){return n/2}",
|
||||||
|
"var o=console.log.bind(console);",
|
||||||
|
'function c(n){o("Foo:",2*n)}',
|
||||||
|
"var a=n(3),b=r(12);",
|
||||||
|
'o("qux",a,b),c(11);',
|
||||||
|
].join(""));
|
||||||
assert.strictEqual(run_code(compressed), run_code(original));
|
assert.strictEqual(run_code(compressed), run_code(original));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not parse invalid use of reserved words", function() {
|
it("Should avoid mangled names in cache", function() {
|
||||||
|
var cache = {};
|
||||||
|
var original = "";
|
||||||
|
var compressed = "";
|
||||||
|
[
|
||||||
|
'"xxxyy";var i={s:1};',
|
||||||
|
'"xxyyy";var j={t:2,u:3},k=4;',
|
||||||
|
'console.log(i.s,j.t,j.u,k);',
|
||||||
|
].forEach(function(code) {
|
||||||
|
var result = Uglify.minify(code, {
|
||||||
|
compress: false,
|
||||||
|
mangle: {
|
||||||
|
properties: true,
|
||||||
|
toplevel: true
|
||||||
|
},
|
||||||
|
nameCache: cache
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
original += code;
|
||||||
|
compressed += result.code;
|
||||||
|
});
|
||||||
|
assert.strictEqual(compressed, [
|
||||||
|
'"xxxyy";var x={x:1};',
|
||||||
|
'"xxyyy";var y={y:2,a:3},a=4;',
|
||||||
|
'console.log(x.x,y.y,y.a,a);',
|
||||||
|
].join(""));
|
||||||
|
assert.strictEqual(run_code(compressed), run_code(original));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should not parse invalid use of reserved words", function() {
|
||||||
assert.strictEqual(Uglify.minify("function enum(){}").error, undefined);
|
assert.strictEqual(Uglify.minify("function enum(){}").error, undefined);
|
||||||
assert.strictEqual(Uglify.minify("function static(){}").error, undefined);
|
assert.strictEqual(Uglify.minify("function static(){}").error, undefined);
|
||||||
assert.strictEqual(Uglify.minify("function super(){}").error.message, "Unexpected token: name (super)");
|
assert.strictEqual(Uglify.minify("function super(){}").error.message, "Unexpected token: name (super)");
|
||||||
@@ -361,4 +404,18 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(stat.print_to_string(), "a=x()");
|
assert.strictEqual(stat.print_to_string(), "a=x()");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("rename", function() {
|
||||||
|
it("Should be repeatable", function() {
|
||||||
|
var code = "!function(x){return x(x)}(y);";
|
||||||
|
for (var i = 0; i < 2; i++) {
|
||||||
|
assert.strictEqual(Uglify.minify(code, {
|
||||||
|
compress: {
|
||||||
|
toplevel: true,
|
||||||
|
},
|
||||||
|
rename: true,
|
||||||
|
}).code, "var a;(a=y)(a);");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,18 +8,6 @@ describe("Yield", function() {
|
|||||||
assert.strictEqual(result.code, 'function*foo(e){return yield 1,yield 2,3}');
|
assert.strictEqual(result.code, 'function*foo(e){return yield 1,yield 2,3}');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should not allow yield as labelIdentifier within generators", function() {
|
|
||||||
var js = "function* g() {yield: 1}"
|
|
||||||
var test = function() {
|
|
||||||
UglifyJS.parse(js);
|
|
||||||
}
|
|
||||||
var expect = function(e) {
|
|
||||||
return e instanceof UglifyJS.JS_Parse_Error &&
|
|
||||||
e.message === "Yield cannot be used as label inside generators";
|
|
||||||
}
|
|
||||||
assert.throws(test, expect);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should not allow yield* followed by a semicolon in generators", function() {
|
it("Should not allow yield* followed by a semicolon in generators", function() {
|
||||||
var js = "function* test() {yield*\n;}";
|
var js = "function* test() {yield*\n;}";
|
||||||
var test = function() {
|
var test = function() {
|
||||||
@@ -65,42 +53,68 @@ describe("Yield", function() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var identifiers = [
|
||||||
|
// Fail in as_symbol
|
||||||
|
'import yield from "bar";',
|
||||||
|
'yield = 123;',
|
||||||
|
'yield: "123";',
|
||||||
|
'for(;;){break yield;}',
|
||||||
|
'for(;;){continue yield;}',
|
||||||
|
'function yield(){}',
|
||||||
|
'try { new Error("")} catch (yield) {}',
|
||||||
|
'var yield = "foo";',
|
||||||
|
'class yield {}',
|
||||||
|
// Fail in as_property_name
|
||||||
|
'var foo = {yield};',
|
||||||
|
];
|
||||||
|
|
||||||
it("Should not allow yield to be used as symbol, identifier or shorthand property outside generators in strict mode", function() {
|
it("Should not allow yield to be used as symbol, identifier or shorthand property outside generators in strict mode", function() {
|
||||||
var tests = [
|
function fail(e) {
|
||||||
// Fail in as_symbol
|
|
||||||
'"use strict"; import yield from "bar";',
|
|
||||||
'"use strict"; yield = 123;',
|
|
||||||
'"use strict"; yield: "123";',
|
|
||||||
'"use strict"; for(;;){break yield;}',
|
|
||||||
'"use strict"; for(;;){continue yield;}',
|
|
||||||
'"use strict"; function yield(){}',
|
|
||||||
'"use strict"; function foo(...yield){}',
|
|
||||||
'"use strict"; try { new Error("")} catch (yield) {}',
|
|
||||||
'"use strict"; var yield = "foo";',
|
|
||||||
'"use strict"; class yield {}',
|
|
||||||
|
|
||||||
// Fail in maybe_assign
|
|
||||||
'"use strict"; var foo = yield;',
|
|
||||||
'"use strict"; var foo = bar = yield',
|
|
||||||
|
|
||||||
// Fail in as_property_name
|
|
||||||
'"use strict"; var foo = {yield};',
|
|
||||||
];
|
|
||||||
|
|
||||||
var fail = function(e) {
|
|
||||||
return e instanceof UglifyJS.JS_Parse_Error &&
|
return e instanceof UglifyJS.JS_Parse_Error &&
|
||||||
/^Unexpected yield identifier (?:as parameter )?inside strict mode/.test(e.message);
|
/^Unexpected yield identifier (?:as parameter )?inside strict mode/.test(e.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
var test = function(input) {
|
function test(input) {
|
||||||
return function() {
|
return function() {
|
||||||
UglifyJS.parse(input);
|
UglifyJS.parse(input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
identifiers.concat([
|
||||||
assert.throws(test(tests[i]), fail, tests[i]);
|
// Fail in as_symbol
|
||||||
|
"function foo(...yield){}",
|
||||||
|
// Fail in maybe_assign
|
||||||
|
'var foo = yield;',
|
||||||
|
'var foo = bar = yield',
|
||||||
|
]).map(function(code) {
|
||||||
|
return '"use strict"; ' + code;
|
||||||
|
}).forEach(function(code) {
|
||||||
|
assert.throws(test(code), fail, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should not allow yield to be used as symbol, identifier or shorthand property inside generators", function() {
|
||||||
|
function fail(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error && [
|
||||||
|
"Unexpected token: operator (=)",
|
||||||
|
"Yield cannot be used as identifier inside generators",
|
||||||
|
].indexOf(e.message) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function test(input) {
|
||||||
|
return function() {
|
||||||
|
UglifyJS.parse(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
identifiers.map(function(code) {
|
||||||
|
return "function* f() { " + code + " }";
|
||||||
|
}).concat([
|
||||||
|
// Fail in as_symbol
|
||||||
|
"function* f(yield) {}",
|
||||||
|
]).forEach(function(code) {
|
||||||
|
assert.throws(test(code), fail, code);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should allow yield to be used as class/object property name", function() {
|
it("Should allow yield to be used as class/object property name", function() {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ var semver = require("semver");
|
|||||||
var tests_dir = path.dirname(module.filename);
|
var tests_dir = path.dirname(module.filename);
|
||||||
var failures = 0;
|
var failures = 0;
|
||||||
var failed_files = {};
|
var failed_files = {};
|
||||||
|
var minify_options = require("./ufuzz.json").map(JSON.stringify);
|
||||||
|
|
||||||
run_compress_tests();
|
run_compress_tests();
|
||||||
if (failures) {
|
if (failures) {
|
||||||
@@ -100,6 +101,15 @@ function run_compress_tests() {
|
|||||||
quote_style: 3,
|
quote_style: 3,
|
||||||
keep_quoted_props: true
|
keep_quoted_props: true
|
||||||
});
|
});
|
||||||
|
try {
|
||||||
|
U.parse(input_code);
|
||||||
|
} catch (ex) {
|
||||||
|
log("!!! Cannot parse input\n---INPUT---\n{input}\n--PARSE ERROR--\n{error}\n\n", {
|
||||||
|
input: input_formatted,
|
||||||
|
error: ex,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
var options = U.defaults(test.options, {
|
var options = U.defaults(test.options, {
|
||||||
warnings: false
|
warnings: false
|
||||||
});
|
});
|
||||||
@@ -139,78 +149,74 @@ function run_compress_tests() {
|
|||||||
output: output,
|
output: output,
|
||||||
expected: expect
|
expected: expect
|
||||||
});
|
});
|
||||||
failures++;
|
return false;
|
||||||
failed_files[file] = 1;
|
|
||||||
}
|
}
|
||||||
else {
|
// expect == output
|
||||||
// expect == output
|
try {
|
||||||
try {
|
U.parse(output);
|
||||||
var reparsed_ast = U.parse(output);
|
} catch (ex) {
|
||||||
} catch (ex) {
|
log("!!! Test matched expected result but cannot parse output\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n--REPARSE ERROR--\n{error}\n\n", {
|
||||||
log("!!! Test matched expected result but cannot parse output\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n--REPARSE ERROR--\n{error}\n\n", {
|
input: input_formatted,
|
||||||
|
output: output,
|
||||||
|
error: ex,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (test.expect_warnings) {
|
||||||
|
U.AST_Node.warn_function = original_warn_function;
|
||||||
|
var expected_warnings = make_code(test.expect_warnings, {
|
||||||
|
beautify: false,
|
||||||
|
quote_style: 2, // force double quote to match JSON
|
||||||
|
});
|
||||||
|
warnings_emitted = warnings_emitted.map(function(input) {
|
||||||
|
return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/");
|
||||||
|
});
|
||||||
|
var actual_warnings = JSON.stringify(warnings_emitted);
|
||||||
|
if (expected_warnings != actual_warnings) {
|
||||||
|
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED WARNINGS---\n{expected_warnings}\n---ACTUAL WARNINGS---\n{actual_warnings}\n\n", {
|
||||||
input: input_formatted,
|
input: input_formatted,
|
||||||
output: output,
|
expected_warnings: expected_warnings,
|
||||||
error: ex.toString(),
|
actual_warnings: actual_warnings,
|
||||||
});
|
});
|
||||||
failures++;
|
return false;
|
||||||
failed_files[file] = 1;
|
|
||||||
}
|
|
||||||
if (test.expect_warnings) {
|
|
||||||
U.AST_Node.warn_function = original_warn_function;
|
|
||||||
var expected_warnings = make_code(test.expect_warnings, {
|
|
||||||
beautify: false,
|
|
||||||
quote_style: 2, // force double quote to match JSON
|
|
||||||
});
|
|
||||||
warnings_emitted = warnings_emitted.map(function(input) {
|
|
||||||
return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/");
|
|
||||||
});
|
|
||||||
var actual_warnings = JSON.stringify(warnings_emitted);
|
|
||||||
if (expected_warnings != actual_warnings) {
|
|
||||||
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED WARNINGS---\n{expected_warnings}\n---ACTUAL WARNINGS---\n{actual_warnings}\n\n", {
|
|
||||||
input: input_formatted,
|
|
||||||
expected_warnings: expected_warnings,
|
|
||||||
actual_warnings: actual_warnings,
|
|
||||||
});
|
|
||||||
failures++;
|
|
||||||
failed_files[file] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (test.expect_stdout
|
|
||||||
&& (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
|
||||||
var stdout = sandbox.run_code(input_code);
|
|
||||||
if (test.expect_stdout === true) {
|
|
||||||
test.expect_stdout = stdout;
|
|
||||||
}
|
|
||||||
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
|
||||||
log("!!! Invalid input or expected stdout\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
|
||||||
input: input_formatted,
|
|
||||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
|
||||||
expected: test.expect_stdout,
|
|
||||||
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
|
||||||
actual: stdout,
|
|
||||||
});
|
|
||||||
failures++;
|
|
||||||
failed_files[file] = 1;
|
|
||||||
} else {
|
|
||||||
stdout = sandbox.run_code(output);
|
|
||||||
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
|
||||||
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
|
||||||
input: input_formatted,
|
|
||||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
|
||||||
expected: test.expect_stdout,
|
|
||||||
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
|
||||||
actual: stdout,
|
|
||||||
});
|
|
||||||
failures++;
|
|
||||||
failed_files[file] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (test.expect_stdout
|
||||||
|
&& (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
||||||
|
var stdout = sandbox.run_code(input_code);
|
||||||
|
if (test.expect_stdout === true) {
|
||||||
|
test.expect_stdout = stdout;
|
||||||
|
}
|
||||||
|
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
||||||
|
log("!!! Invalid input or expected stdout\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
||||||
|
input: input_formatted,
|
||||||
|
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
|
expected: test.expect_stdout,
|
||||||
|
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
|
actual: stdout,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
stdout = sandbox.run_code(output);
|
||||||
|
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
||||||
|
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
||||||
|
input: input_formatted,
|
||||||
|
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
|
expected: test.expect_stdout,
|
||||||
|
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
|
actual: stdout,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
var tests = parse_test(path.resolve(dir, file));
|
var tests = parse_test(path.resolve(dir, file));
|
||||||
for (var i in tests) if (tests.hasOwnProperty(i)) {
|
for (var i in tests) if (tests.hasOwnProperty(i)) {
|
||||||
test_case(tests[i]);
|
if (!test_case(tests[i])) {
|
||||||
|
failures++;
|
||||||
|
failed_files[file] = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
files.forEach(function(file){
|
files.forEach(function(file){
|
||||||
@@ -346,3 +352,46 @@ function evaluate(code) {
|
|||||||
code = make_code(code, { beautify: true });
|
code = make_code(code, { beautify: true });
|
||||||
return new Function("return(" + code + ")")();
|
return new Function("return(" + code + ")")();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to reminify original input with standard options
|
||||||
|
// to see if it matches expect_stdout.
|
||||||
|
function reminify(orig_options, input_code, input_formatted, expect_stdout) {
|
||||||
|
for (var i = 0; i < minify_options.length; i++) {
|
||||||
|
var options = JSON.parse(minify_options[i]);
|
||||||
|
if (options.compress) [
|
||||||
|
"keep_fargs",
|
||||||
|
"keep_fnames",
|
||||||
|
].forEach(function(name) {
|
||||||
|
if (name in orig_options) {
|
||||||
|
options.compress[name] = orig_options[name];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var options_formatted = JSON.stringify(options, null, 4);
|
||||||
|
var result = U.minify(input_code, options);
|
||||||
|
if (result.error) {
|
||||||
|
log("!!! failed input reminify\n---INPUT---\n{input}\n--ERROR---\n{error}\n\n", {
|
||||||
|
input: input_formatted,
|
||||||
|
error: result.error,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
var stdout = sandbox.run_code(result.code);
|
||||||
|
if (typeof expect_stdout != "string" && typeof stdout != "string" && expect_stdout.name == stdout.name) {
|
||||||
|
stdout = expect_stdout;
|
||||||
|
}
|
||||||
|
if (!sandbox.same_stdout(expect_stdout, stdout)) {
|
||||||
|
log("!!! failed running reminified input\n---INPUT---\n{input}\n---OPTIONS---\n{options}\n---OUTPUT---\n{output}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
||||||
|
input: input_formatted,
|
||||||
|
options: options_formatted,
|
||||||
|
output: result.code,
|
||||||
|
expected_type: typeof expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
|
expected: expect_stdout,
|
||||||
|
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
|
actual: stdout,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,11 +6,7 @@
|
|||||||
// bin/uglifyjs s.js -c && bin/uglifyjs s.js -c passes=3 && bin/uglifyjs s.js -c passes=3 -m
|
// bin/uglifyjs s.js -c && bin/uglifyjs s.js -c passes=3 && bin/uglifyjs s.js -c passes=3 -m
|
||||||
// cat s.js | node && node s.js && bin/uglifyjs s.js -c | node && bin/uglifyjs s.js -c passes=3 | node && bin/uglifyjs s.js -c passes=3 -m | node
|
// cat s.js | node && node s.js && bin/uglifyjs s.js -c | node && bin/uglifyjs s.js -c passes=3 | node && bin/uglifyjs s.js -c passes=3 -m | node
|
||||||
|
|
||||||
// workaround for tty output truncation upon process.exit()
|
require("../tools/exit");
|
||||||
[process.stdout, process.stderr].forEach(function(stream){
|
|
||||||
if (stream._handle && stream._handle.setBlocking)
|
|
||||||
stream._handle.setBlocking(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
var UglifyJS = require("..");
|
var UglifyJS = require("..");
|
||||||
var randomBytes = require("crypto").randomBytes;
|
var randomBytes = require("crypto").randomBytes;
|
||||||
@@ -127,6 +123,9 @@ for (var i = 2; i < process.argv.length; ++i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var VALUES = [
|
var VALUES = [
|
||||||
|
'"a"',
|
||||||
|
'"b"',
|
||||||
|
'"c"',
|
||||||
'""',
|
'""',
|
||||||
'true',
|
'true',
|
||||||
'false',
|
'false',
|
||||||
@@ -329,7 +328,8 @@ function createTopLevelCode() {
|
|||||||
rng(2) == 0
|
rng(2) == 0
|
||||||
? createStatements(3, MAX_GENERATION_RECURSION_DEPTH, CANNOT_THROW, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, 0)
|
? createStatements(3, MAX_GENERATION_RECURSION_DEPTH, CANNOT_THROW, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, 0)
|
||||||
: createFunctions(rng(MAX_GENERATED_TOPLEVELS_PER_RUN) + 1, MAX_GENERATION_RECURSION_DEPTH, DEFUN_OK, CANNOT_THROW, 0),
|
: createFunctions(rng(MAX_GENERATED_TOPLEVELS_PER_RUN) + 1, MAX_GENERATION_RECURSION_DEPTH, DEFUN_OK, CANNOT_THROW, 0),
|
||||||
'console.log(null, a, b, c);' // preceding `null` makes for a cleaner output (empty string still shows up etc)
|
// preceding `null` makes for a cleaner output (empty string still shows up etc)
|
||||||
|
'console.log(null, a, b, c, Infinity, NaN, undefined);'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,6 +635,8 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
case p++:
|
case p++:
|
||||||
case p++:
|
case p++:
|
||||||
return getVarName();
|
return getVarName();
|
||||||
|
case p++:
|
||||||
|
return getVarName() + createAssignment() + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow);
|
||||||
case p++:
|
case p++:
|
||||||
return createExpression(recurmax, COMMA_OK, stmtDepth, canThrow);
|
return createExpression(recurmax, COMMA_OK, stmtDepth, canThrow);
|
||||||
case p++:
|
case p++:
|
||||||
|
|||||||
15
tools/exit.js
Normal file
15
tools/exit.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
// workaround for tty output truncation upon process.exit()
|
||||||
|
var exit = process.exit;
|
||||||
|
process.exit = function() {
|
||||||
|
var args = [].slice.call(arguments);
|
||||||
|
process.once("uncaughtException", function() {
|
||||||
|
(function callback() {
|
||||||
|
if (process.stdout.bufferSize || process.stderr.bufferSize) {
|
||||||
|
setImmediate(callback);
|
||||||
|
} else {
|
||||||
|
exit.apply(process, args);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
});
|
||||||
|
throw exit;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user