Compare commits
111 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a6e58109e | ||
|
|
5ac6ec5496 | ||
|
|
eb22f0101e | ||
|
|
e4bff315eb | ||
|
|
001f6f9719 | ||
|
|
e0b302d651 | ||
|
|
fa2511f71c | ||
|
|
edf1bf1106 | ||
|
|
88dfc49683 | ||
|
|
9dec612cd5 | ||
|
|
02d966d914 | ||
|
|
5b5f6e329c | ||
|
|
4e4a2f8ed3 | ||
|
|
32bd65a87f | ||
|
|
318206d41d | ||
|
|
535212c69e | ||
|
|
1d42e9ad55 | ||
|
|
78f354beb8 | ||
|
|
e012f046bc | ||
|
|
f63b7b079d | ||
|
|
d530f9332c | ||
|
|
10bc86ba10 | ||
|
|
15b608f74c | ||
|
|
7c52af0dec | ||
|
|
cd97237c59 | ||
|
|
965e9767e5 | ||
|
|
41a7000745 | ||
|
|
9cdc1ef6c2 | ||
|
|
4db81065ee | ||
|
|
4653e8aec0 | ||
|
|
ac002b6338 | ||
|
|
9eea3a673a | ||
|
|
d6d2f5ced2 | ||
|
|
887e086890 | ||
|
|
8602d1ba17 | ||
|
|
dd90135944 | ||
|
|
612701a706 | ||
|
|
503532cf77 | ||
|
|
6c0e522922 | ||
|
|
9d37276986 | ||
|
|
5a4cd09938 | ||
|
|
c32fe26b8d | ||
|
|
2c3c4ec323 | ||
|
|
f451a7ad79 | ||
|
|
07953b36b0 | ||
|
|
387c69b194 | ||
|
|
a9d9af53e9 | ||
|
|
8a07f1202c | ||
|
|
41b65af6e2 | ||
|
|
884842cd6c | ||
|
|
8076d66ae5 | ||
|
|
64e3ceec3b | ||
|
|
672cdfa57a | ||
|
|
e39f33e41b | ||
|
|
6667440aaf | ||
|
|
ab5c7e6863 | ||
|
|
08c386f363 | ||
|
|
937a672879 | ||
|
|
513995f57d | ||
|
|
db6fd6db3e | ||
|
|
da930affd2 | ||
|
|
996836b67e | ||
|
|
fc7678c115 | ||
|
|
b371dc2d1e | ||
|
|
56e9454f1f | ||
|
|
d67daa8314 | ||
|
|
f0120e90b6 | ||
|
|
ec4558be29 | ||
|
|
685ab357cc | ||
|
|
5792f30175 | ||
|
|
24443b6764 | ||
|
|
154edf0427 | ||
|
|
4778cf88e2 | ||
|
|
38bd4f65d0 | ||
|
|
0b808f6428 | ||
|
|
b2bc2e1173 | ||
|
|
80787ff7ef | ||
|
|
b92a89f325 | ||
|
|
902292f776 | ||
|
|
3dcf098468 | ||
|
|
d89f0965aa | ||
|
|
c8d98f4787 | ||
|
|
0207b46d70 | ||
|
|
aa2a9fbedb | ||
|
|
3596b4feda | ||
|
|
51deeff72e | ||
|
|
4c227cc6bd | ||
|
|
2426657daa | ||
|
|
e1b03d0235 | ||
|
|
f1b3e9df1e | ||
|
|
fcc87edb71 | ||
|
|
8b464331ba | ||
|
|
9f57920566 | ||
|
|
933ca9ddd8 | ||
|
|
74e36e4456 | ||
|
|
4382bfe848 | ||
|
|
b6f250f5c9 | ||
|
|
5d69545299 | ||
|
|
139fad0c05 | ||
|
|
99946a3993 | ||
|
|
053cb27fe3 | ||
|
|
25017978e7 | ||
|
|
f749863cb2 | ||
|
|
123f9cf987 | ||
|
|
a758b40e3f | ||
|
|
44e5e99aae | ||
|
|
be53c4838b | ||
|
|
0c7b016fa7 | ||
|
|
00665766da | ||
|
|
88b4283200 | ||
|
|
d2bd0d1c1c |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -50,7 +50,7 @@ jobs:
|
||||
OPTIONS: ${{ matrix.options }}
|
||||
SCRIPT: ${{ matrix.script }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Perform uglify, build & test
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
5
.github/workflows/ci.yml
vendored
5
.github/workflows/ci.yml
vendored
@@ -15,9 +15,10 @@ jobs:
|
||||
env:
|
||||
NODE: ${{ matrix.node }}
|
||||
TYPE: ${{ matrix.script }}
|
||||
UGLIFY_GITHUB_LAG: 10000
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: tmp
|
||||
key: tmp ${{ matrix.script }}
|
||||
|
||||
2
.github/workflows/ufuzz.yml
vendored
2
.github/workflows/ufuzz.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
||||
env:
|
||||
NODE: ${{ matrix.node }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Perform fuzzing
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
80
README.md
80
README.md
@@ -54,8 +54,6 @@ a double dash to prevent input files being used as option arguments:
|
||||
modules and Userscripts that may
|
||||
be anonymous function wrapped (IIFE)
|
||||
by the .user.js engine `caller`.
|
||||
`expression` Parse a single expression, rather than
|
||||
a program (for parsing JSON).
|
||||
`spidermonkey` Assume input files are SpiderMonkey
|
||||
AST format (as JSON).
|
||||
-c, --compress [options] Enable compressor/specify compressor options:
|
||||
@@ -111,6 +109,8 @@ a double dash to prevent input files being used as option arguments:
|
||||
-d, --define <expr>[=value] Global definitions.
|
||||
-e, --enclose [arg[:value]] Embed everything in a big function, with configurable
|
||||
argument(s) & value(s).
|
||||
--expression Parse a single expression, rather than a program
|
||||
(for parsing JSON).
|
||||
--ie Support non-standard Internet Explorer.
|
||||
Equivalent to setting `ie: true` in `minify()`
|
||||
for `compress`, `mangle` and `output` options.
|
||||
@@ -327,7 +327,7 @@ unquoted style (`o.foo`). Example:
|
||||
// stuff.js
|
||||
var o = {
|
||||
"foo": 1,
|
||||
bar: 3
|
||||
bar: 3,
|
||||
};
|
||||
o.foo += o.bar;
|
||||
console.log(o.foo);
|
||||
@@ -339,6 +339,16 @@ $ uglifyjs stuff.js --mangle-props keep_quoted -c -m
|
||||
var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo);
|
||||
```
|
||||
|
||||
If the minified output will be processed again by UglifyJS, consider specifying
|
||||
`keep_quoted_props` so the same property names are preserved:
|
||||
|
||||
```bash
|
||||
$ uglifyjs stuff.js --mangle-props keep_quoted -c -m -O keep_quoted_props
|
||||
```
|
||||
```javascript
|
||||
var o={"foo":1,o:3};o.foo+=o.o,console.log(o.foo);
|
||||
```
|
||||
|
||||
### Debugging property name mangling
|
||||
|
||||
You can also pass `--mangle-props debug` in order to mangle property names
|
||||
@@ -504,6 +514,8 @@ if (result.error) throw result.error;
|
||||
- `compress` (default: `{}`) — pass `false` to skip compressing entirely.
|
||||
Pass an object to specify custom [compress options](#compress-options).
|
||||
|
||||
- `expression` (default: `false`) — parse as a single expression, e.g. JSON.
|
||||
|
||||
- `ie` (default: `false`) — enable workarounds for Internet Explorer bugs.
|
||||
|
||||
- `keep_fargs` (default: `false`) — pass `true` to prevent discarding or mangling
|
||||
@@ -519,7 +531,8 @@ if (result.error) throw result.error;
|
||||
Pass an object to specify custom [mangle property options](#mangle-properties-options).
|
||||
|
||||
- `module` (default: `false`) — set to `true` if you wish to process input as
|
||||
ES module, i.e. implicit `"use strict";` alongside with `toplevel` enabled.
|
||||
ES module, i.e. implicit `"use strict";` and support for top-level `await`,
|
||||
alongside with `toplevel` enabled.
|
||||
|
||||
- `nameCache` (default: `null`) — pass an empty object `{}` or a previously
|
||||
used `nameCache` object if you wish to cache mangled variable and
|
||||
@@ -632,7 +645,11 @@ to be `false` and all symbol names will be omitted.
|
||||
|
||||
- `bare_returns` (default: `false`) — support top level `return` statements
|
||||
|
||||
- `html5_comments` (default: `true`)
|
||||
- `html5_comments` (default: `true`) — process HTML comment as workaround for
|
||||
browsers which do not recognise `<script>` tags
|
||||
|
||||
- `module` (default: `false`) — set to `true` if you wish to process input as
|
||||
ES module, i.e. implicit `"use strict";` and support for top-level `await`.
|
||||
|
||||
- `shebang` (default: `true`) — support `#!command` as the first line
|
||||
|
||||
@@ -811,8 +828,9 @@ to be `false` and all symbol names will be omitted.
|
||||
|
||||
- `unsafe` (default: `false`) — apply "unsafe" transformations (discussion below)
|
||||
|
||||
- `unsafe_comps` (default: `false`) — compress expressions like `a <= b` assuming
|
||||
none of the operands can be (coerced to) `NaN`.
|
||||
- `unsafe_comps` (default: `false`) — assume operands cannot be (coerced to) `NaN`
|
||||
in numeric comparisons, e.g. `a <= b`. In addition, expressions involving `in`
|
||||
or `instanceof` would never throw.
|
||||
|
||||
- `unsafe_Function` (default: `false`) — compress and mangle `Function(args, code)`
|
||||
when both `args` and `code` are string literals.
|
||||
@@ -922,6 +940,9 @@ can pass additional arguments that control the code output:
|
||||
}
|
||||
```
|
||||
|
||||
- `extendscript` (default: `false`) — enable workarounds for Adobe ExtendScript
|
||||
bugs
|
||||
|
||||
- `galio` (default: `false`) — enable workarounds for ANT Galio bugs
|
||||
|
||||
- `indent_level` (default: `4`) — indent by specified number of spaces or the
|
||||
@@ -1351,7 +1372,7 @@ To allow for better optimizations, the compiler makes various assumptions:
|
||||
// SyntaxError: The left-hand side of a for-of loop may not be 'async'.
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Later versions of Chrome and Node.js will give incorrect results with the
|
||||
- Some versions of Chrome and Node.js will give incorrect results with the
|
||||
following:
|
||||
```javascript
|
||||
console.log({
|
||||
@@ -1360,9 +1381,15 @@ To allow for better optimizations, the compiler makes various assumptions:
|
||||
return "FAIL";
|
||||
},
|
||||
[42]: "PASS",
|
||||
}[42], {
|
||||
...console,
|
||||
get 42() {
|
||||
return "FAIL";
|
||||
},
|
||||
42: "PASS",
|
||||
}[42]);
|
||||
// Expected: "PASS"
|
||||
// Actual: "FAIL"
|
||||
// Expected: "PASS PASS"
|
||||
// Actual: "PASS FAIL"
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Earlier versions of JavaScript will throw `TypeError` with the following:
|
||||
@@ -1415,9 +1442,34 @@ To allow for better optimizations, the compiler makes various assumptions:
|
||||
function f() {
|
||||
throw 42;
|
||||
}
|
||||
} catch (e) {}
|
||||
console.log(typeof f);
|
||||
// Expected: "function"
|
||||
// Actual: "undefined"
|
||||
} catch (e) {
|
||||
console.log(typeof f, e);
|
||||
}
|
||||
// Expected: "function 42"
|
||||
// Actual: "undefined 42"
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Later versions of JavaScript will throw `SyntaxError` with the following:
|
||||
```javascript
|
||||
"use strict";
|
||||
console.log(function f() {
|
||||
return f = "PASS";
|
||||
}());
|
||||
// Expected: "PASS"
|
||||
// Actual: TypeError: invalid assignment to const 'f'
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Adobe ExtendScript will give incorrect results with the following:
|
||||
```javascript
|
||||
alert(true ? "PASS" : false ? "FAIL" : null);
|
||||
// Expected: "PASS"
|
||||
// Actual: "FAIL"
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Adobe ExtendScript will give incorrect results with the following:
|
||||
```javascript
|
||||
alert(42 ? null ? "FAIL" : "PASS" : "FAIL");
|
||||
// Expected: "PASS"
|
||||
// Actual: SyntaxError: Expected: :
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
|
||||
65
bin/uglifyjs
65
bin/uglifyjs
@@ -104,6 +104,7 @@ function process_option(name, no_value) {
|
||||
" --config-file <file> Read minify() options from JSON file.",
|
||||
" -d, --define <expr>[=value] Global definitions.",
|
||||
" -e, --enclose [arg[,...][:value[,...]]] Embed everything in a big function, with configurable argument(s) & value(s).",
|
||||
" --expression Parse a single expression, rather than a program.",
|
||||
" --ie Support non-standard Internet Explorer.",
|
||||
" --keep-fargs Do not mangle/drop function arguments.",
|
||||
" --keep-fnames Do not mangle/drop function names. Useful for code relying on Function.prototype.name.",
|
||||
@@ -151,6 +152,7 @@ function process_option(name, no_value) {
|
||||
options[name] = read_value();
|
||||
break;
|
||||
case "annotations":
|
||||
case "expression":
|
||||
case "ie":
|
||||
case "ie8":
|
||||
case "module":
|
||||
@@ -276,6 +278,8 @@ if (specified["self"]) {
|
||||
if (paths.length) UglifyJS.AST_Node.warn("Ignoring input files since --self was passed");
|
||||
if (!options.wrap) options.wrap = "UglifyJS";
|
||||
paths = UglifyJS.FILES;
|
||||
} else if (paths.length) {
|
||||
paths = simple_glob(paths);
|
||||
}
|
||||
if (specified["in-situ"]) {
|
||||
if (output && output != "spidermonkey" || specified["reduce-test"] || specified["self"]) {
|
||||
@@ -290,7 +294,7 @@ if (specified["in-situ"]) {
|
||||
run();
|
||||
});
|
||||
} else if (paths.length) {
|
||||
simple_glob(paths).forEach(function(name) {
|
||||
paths.forEach(function(name) {
|
||||
files[convert_path(name)] = read_file(name);
|
||||
});
|
||||
run();
|
||||
@@ -489,33 +493,42 @@ function fatal(message) {
|
||||
|
||||
// A file glob function that only supports "*" and "?" wildcards in the basename.
|
||||
// Example: "foo/bar/*baz??.*.js"
|
||||
// Argument `glob` may be a string or an array of strings.
|
||||
// Argument `paths` must be an array of strings.
|
||||
// Returns an array of strings. Garbage in, garbage out.
|
||||
function simple_glob(glob) {
|
||||
if (Array.isArray(glob)) {
|
||||
return [].concat.apply([], glob.map(simple_glob));
|
||||
}
|
||||
if (glob.match(/\*|\?/)) {
|
||||
var dir = path.dirname(glob);
|
||||
try {
|
||||
var entries = fs.readdirSync(dir);
|
||||
} catch (ex) {}
|
||||
if (entries) {
|
||||
var pattern = "^" + path.basename(glob)
|
||||
.replace(/[.+^$[\]\\(){}]/g, "\\$&")
|
||||
.replace(/\*/g, "[^/\\\\]*")
|
||||
.replace(/\?/g, "[^/\\\\]") + "$";
|
||||
var mod = process.platform === "win32" ? "i" : "";
|
||||
var rx = new RegExp(pattern, mod);
|
||||
var results = entries.sort().filter(function(name) {
|
||||
return rx.test(name);
|
||||
}).map(function(name) {
|
||||
return path.join(dir, name);
|
||||
});
|
||||
if (results.length) return results;
|
||||
function simple_glob(paths) {
|
||||
return paths.reduce(function(paths, glob) {
|
||||
if (/\*|\?/.test(glob)) {
|
||||
var dir = path.dirname(glob);
|
||||
try {
|
||||
var entries = fs.readdirSync(dir).filter(function(name) {
|
||||
try {
|
||||
return fs.statSync(path.join(dir, name)).isFile();
|
||||
} catch (ex) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} catch (ex) {}
|
||||
if (entries) {
|
||||
var pattern = "^" + path.basename(glob)
|
||||
.replace(/[.+^$[\]\\(){}]/g, "\\$&")
|
||||
.replace(/\*/g, "[^/\\\\]*")
|
||||
.replace(/\?/g, "[^/\\\\]") + "$";
|
||||
var mod = process.platform === "win32" ? "i" : "";
|
||||
var rx = new RegExp(pattern, mod);
|
||||
var results = entries.filter(function(name) {
|
||||
return rx.test(name);
|
||||
}).sort().map(function(name) {
|
||||
return path.join(dir, name);
|
||||
});
|
||||
if (results.length) {
|
||||
[].push.apply(paths, results);
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return [ glob ];
|
||||
paths.push(glob);
|
||||
return paths;
|
||||
}, []);
|
||||
}
|
||||
|
||||
function read_file(path, default_value) {
|
||||
|
||||
306
lib/ast.js
306
lib/ast.js
@@ -109,6 +109,9 @@ var AST_Node = DEFNODE("Node", "start end", {
|
||||
start: "[AST_Token] The first token of this node",
|
||||
end: "[AST_Token] The last token of this node"
|
||||
},
|
||||
equals: function(node) {
|
||||
return this.TYPE == node.TYPE && this._equals(node);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
visitor.visit(this);
|
||||
},
|
||||
@@ -125,12 +128,7 @@ var AST_Node = DEFNODE("Node", "start end", {
|
||||
var marker = {};
|
||||
this.walk(new TreeWalker(function(node) {
|
||||
if (node.validate_visited === marker) {
|
||||
throw new Error(string_template("cannot reuse {type} from [{file}:{line},{col}]", {
|
||||
type: "AST_" + node.TYPE,
|
||||
file: node.start.file,
|
||||
line: node.start.line,
|
||||
col: node.start.col,
|
||||
}));
|
||||
throw new Error(string_template("cannot reuse AST_{TYPE} from [{start}]", node));
|
||||
}
|
||||
node.validate_visited = marker;
|
||||
}));
|
||||
@@ -138,6 +136,7 @@ var AST_Node = DEFNODE("Node", "start end", {
|
||||
}, null);
|
||||
|
||||
DEF_BITPROPS(AST_Node, [
|
||||
// AST_Node
|
||||
"_optimized",
|
||||
"_squeezed",
|
||||
// AST_Call
|
||||
@@ -172,6 +171,8 @@ DEF_BITPROPS(AST_Node, [
|
||||
"pure",
|
||||
// AST_Assign
|
||||
"redundant",
|
||||
// AST_Node
|
||||
"single_use",
|
||||
// AST_ClassProperty
|
||||
"static",
|
||||
// AST_Call
|
||||
@@ -231,6 +232,24 @@ AST_Node.disable_validation = function() {
|
||||
while (restore = restore_transforms.pop()) restore();
|
||||
};
|
||||
|
||||
function all_equals(k, l) {
|
||||
return k.length == l.length && all(k, function(m, i) {
|
||||
return m.equals(l[i]);
|
||||
});
|
||||
}
|
||||
|
||||
function list_equals(s, t) {
|
||||
return s.length == t.length && all(s, function(u, i) {
|
||||
return u == t[i];
|
||||
});
|
||||
}
|
||||
|
||||
function prop_equals(u, v) {
|
||||
if (u === v) return true;
|
||||
if (u == null) return v == null;
|
||||
return u instanceof AST_Node && v instanceof AST_Node && u.equals(v);
|
||||
}
|
||||
|
||||
/* -----[ statements ]----- */
|
||||
|
||||
var AST_Statement = DEFNODE("Statement", null, {
|
||||
@@ -242,6 +261,7 @@ var AST_Statement = DEFNODE("Statement", null, {
|
||||
|
||||
var AST_Debugger = DEFNODE("Debugger", null, {
|
||||
$documentation: "Represents a debugger statement",
|
||||
_equals: return_true,
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_Directive = DEFNODE("Directive", "quote value", {
|
||||
@@ -250,6 +270,9 @@ var AST_Directive = DEFNODE("Directive", "quote value", {
|
||||
quote: "[string?] the original quote character",
|
||||
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.value == node.value;
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.quote != null) {
|
||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
||||
@@ -260,7 +283,8 @@ var AST_Directive = DEFNODE("Directive", "quote value", {
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_EmptyStatement = DEFNODE("EmptyStatement", null, {
|
||||
$documentation: "The empty statement (empty block or simply a semicolon)"
|
||||
$documentation: "The empty statement (empty block or simply a semicolon)",
|
||||
_equals: return_true,
|
||||
}, AST_Statement);
|
||||
|
||||
function is_statement(node) {
|
||||
@@ -291,6 +315,9 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
||||
$propdoc: {
|
||||
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -342,6 +369,9 @@ var AST_Block = DEFNODE("Block", "body", {
|
||||
$propdoc: {
|
||||
body: "[AST_Statement*] an array of statements"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -376,6 +406,10 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
||||
$propdoc: {
|
||||
label: "[AST_Label] a label definition"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.label.equals(node.label)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -417,6 +451,10 @@ var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
||||
$propdoc: {
|
||||
condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body)
|
||||
&& this.condition.equals(node.condition);
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.TYPE == "DWLoop") throw new Error("should not instantiate AST_DWLoop");
|
||||
must_be_expression(this, "condition");
|
||||
@@ -431,7 +469,7 @@ var AST_Do = DEFNODE("Do", null, {
|
||||
node.body.walk(visitor);
|
||||
node.condition.walk(visitor);
|
||||
});
|
||||
}
|
||||
},
|
||||
}, AST_DWLoop);
|
||||
|
||||
var AST_While = DEFNODE("While", null, {
|
||||
@@ -442,7 +480,7 @@ var AST_While = DEFNODE("While", null, {
|
||||
node.condition.walk(visitor);
|
||||
node.body.walk(visitor);
|
||||
});
|
||||
}
|
||||
},
|
||||
}, AST_DWLoop);
|
||||
|
||||
var AST_For = DEFNODE("For", "init condition step", {
|
||||
@@ -452,6 +490,12 @@ var AST_For = DEFNODE("For", "init condition step", {
|
||||
condition: "[AST_Node?] the `for` termination clause, or null if empty",
|
||||
step: "[AST_Node?] the `for` update clause, or null if empty"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.init, node.init)
|
||||
&& prop_equals(this.condition, node.condition)
|
||||
&& prop_equals(this.step, node.step)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -479,6 +523,11 @@ var AST_ForEnumeration = DEFNODE("ForEnumeration", "init object", {
|
||||
init: "[AST_Node] the assignment target during iteration",
|
||||
object: "[AST_Node] the object to iterate over"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.init.equals(node.init)
|
||||
&& this.object.equals(node.object)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -519,6 +568,10 @@ var AST_With = DEFNODE("With", "expression", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] the `with` expression"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -534,7 +587,7 @@ var AST_With = DEFNODE("With", "expression", {
|
||||
/* -----[ scope and functions ]----- */
|
||||
|
||||
var AST_Scope = DEFNODE("Scope", "fn_defs may_call_this uses_eval uses_with", {
|
||||
$documentation: "Base class for all statements introducing a lexical scope",
|
||||
$documentation: "Base class for all statements introducing a lambda scope",
|
||||
$propdoc: {
|
||||
uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`",
|
||||
uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
|
||||
@@ -592,6 +645,10 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||
}
|
||||
}, AST_Scope);
|
||||
|
||||
var AST_ClassInitBlock = DEFNODE("ClassInitBlock", null, {
|
||||
$documentation: "Value for `class` static initialization blocks",
|
||||
}, AST_Scope);
|
||||
|
||||
var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest safe_ids uses_arguments", {
|
||||
$documentation: "Base class for functions",
|
||||
$propdoc: {
|
||||
@@ -617,6 +674,13 @@ var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest safe_ids uses_argu
|
||||
});
|
||||
if (this.rest) this.rest.walk(tw);
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.rest, node.rest)
|
||||
&& prop_equals(this.name, node.name)
|
||||
&& prop_equals(this.value, node.value)
|
||||
&& all_equals(this.argnames, node.argnames)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -827,6 +891,11 @@ var AST_Class = DEFNODE("Class", "extends name properties", {
|
||||
extends: "[AST_Node?] the super class, or null if not specified",
|
||||
properties: "[AST_ClassProperty*] array of class properties",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.name, node.name)
|
||||
&& prop_equals(this.extends, node.extends)
|
||||
&& all_equals(this.properties, node.properties);
|
||||
},
|
||||
resolve: function(def_class) {
|
||||
return def_class ? this : this.parent_scope.resolve();
|
||||
},
|
||||
@@ -874,11 +943,17 @@ var AST_ClassExpression = DEFNODE("ClassExpression", null, {
|
||||
var AST_ClassProperty = DEFNODE("ClassProperty", "key private static value", {
|
||||
$documentation: "Base class for `class` properties",
|
||||
$propdoc: {
|
||||
key: "[string|AST_Node] property name (AST_Node for computed property)",
|
||||
key: "[string|AST_Node?] property name (AST_Node for computed property, null for initialization block)",
|
||||
private: "[boolean] whether this is a private property",
|
||||
static: "[boolean] whether this is a static property",
|
||||
value: "[AST_Node?] property value (AST_Accessor for getters/setters, AST_LambdaExpression for methods, null if not specified for fields)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.private == !node.private
|
||||
&& !this.static == !node.static
|
||||
&& prop_equals(this.key, node.key)
|
||||
&& prop_equals(this.value, node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -888,7 +963,9 @@ var AST_ClassProperty = DEFNODE("ClassProperty", "key private static value", {
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.TYPE == "ClassProperty") throw new Error("should not instantiate AST_ClassProperty");
|
||||
if (typeof this.key != "string") {
|
||||
if (this instanceof AST_ClassInit) {
|
||||
if (this.key != null) throw new Error("key must be null");
|
||||
} else if (typeof this.key != "string") {
|
||||
if (!(this.key instanceof AST_Node)) throw new Error("key must be string or AST_Node");
|
||||
must_be_expression(this, "key");
|
||||
}
|
||||
@@ -928,6 +1005,17 @@ var AST_ClassMethod = DEFNODE("ClassMethod", null, {
|
||||
},
|
||||
}, AST_ClassProperty);
|
||||
|
||||
var AST_ClassInit = DEFNODE("ClassInit", null, {
|
||||
$documentation: "A `class` static initialization block",
|
||||
_validate: function() {
|
||||
if (!this.static) throw new Error("static must be true");
|
||||
if (!(this.value instanceof AST_ClassInitBlock)) throw new Error("value must be AST_ClassInitBlock");
|
||||
},
|
||||
initialize: function() {
|
||||
this.static = true;
|
||||
},
|
||||
}, AST_ClassProperty);
|
||||
|
||||
/* -----[ JUMPS ]----- */
|
||||
|
||||
var AST_Jump = DEFNODE("Jump", null, {
|
||||
@@ -942,6 +1030,9 @@ var AST_Exit = DEFNODE("Exit", "value", {
|
||||
$propdoc: {
|
||||
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.value, node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -972,6 +1063,9 @@ var AST_LoopControl = DEFNODE("LoopControl", "label", {
|
||||
$propdoc: {
|
||||
label: "[AST_LabelRef?] the label, or null if none",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.label, node.label);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1002,6 +1096,11 @@ var AST_If = DEFNODE("If", "condition alternative", {
|
||||
condition: "[AST_Node] the `if` condition",
|
||||
alternative: "[AST_Statement?] the `else` part, or null if not present"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body)
|
||||
&& this.condition.equals(node.condition)
|
||||
&& prop_equals(this.alternative, node.alternative);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1025,6 +1124,10 @@ var AST_Switch = DEFNODE("Switch", "expression", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] the `switch` “discriminant”"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1056,6 +1159,10 @@ var AST_Case = DEFNODE("Case", "expression", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] the `case` expression"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1076,6 +1183,11 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
|
||||
bcatch: "[AST_Catch?] the catch block, or null if not present",
|
||||
bfinally: "[AST_Finally?] the finally block, or null if not present"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.body, node.body)
|
||||
&& prop_equals(this.bcatch, node.bcatch)
|
||||
&& prop_equals(this.bfinally, node.bfinally);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1099,6 +1211,10 @@ var AST_Catch = DEFNODE("Catch", "argname", {
|
||||
$propdoc: {
|
||||
argname: "[(AST_Destructured|AST_SymbolCatch)?] symbol for the exception, or null if not present",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.argname, node.argname)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1124,6 +1240,9 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
||||
$propdoc: {
|
||||
definitions: "[AST_VarDef*] array of variable definitions"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.definitions, node.definitions);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1180,6 +1299,10 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
|
||||
name: "[AST_Destructured|AST_SymbolVar] name of the variable",
|
||||
value: "[AST_Node?] initializer, or null of there's no initializer",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name.equals(node.name)
|
||||
&& prop_equals(this.value, node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1199,6 +1322,9 @@ var AST_ExportDeclaration = DEFNODE("ExportDeclaration", "body", {
|
||||
$propdoc: {
|
||||
body: "[AST_DefClass|AST_Definitions|AST_LambdaDefinition] the statement to export",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1219,6 +1345,9 @@ var AST_ExportDefault = DEFNODE("ExportDefault", "body", {
|
||||
$propdoc: {
|
||||
body: "[AST_Node] the default export",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1232,29 +1361,29 @@ var AST_ExportDefault = DEFNODE("ExportDefault", "body", {
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path quote", {
|
||||
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path", {
|
||||
$documentation: "An `export ... from '...'` statement",
|
||||
$propdoc: {
|
||||
aliases: "[string*] array of aliases to export",
|
||||
keys: "[string*] array of keys to import",
|
||||
path: "[string] the path to import module",
|
||||
quote: "[string?] the original quote character",
|
||||
aliases: "[AST_String*] array of aliases to export",
|
||||
keys: "[AST_String*] array of keys to import",
|
||||
path: "[AST_String] the path to import module",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.path.equals(node.path)
|
||||
&& all_equals(this.aliases, node.aliases)
|
||||
&& all_equals(this.keys, node.keys);
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.aliases.length != this.keys.length) {
|
||||
throw new Error("aliases:key length mismatch: " + this.aliases.length + " != " + this.keys.length);
|
||||
}
|
||||
this.aliases.forEach(function(name) {
|
||||
if (typeof name != "string") throw new Error("aliases must contain string");
|
||||
if (!(name instanceof AST_String)) throw new Error("aliases must contain AST_String");
|
||||
});
|
||||
this.keys.forEach(function(name) {
|
||||
if (typeof name != "string") throw new Error("keys must contain string");
|
||||
if (!(name instanceof AST_String)) throw new Error("keys must contain AST_String");
|
||||
});
|
||||
if (typeof this.path != "string") throw new Error("path must be string");
|
||||
if (this.quote != null) {
|
||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
||||
if (!/^["']$/.test(this.quote)) throw new Error("invalid quote: " + this.quote);
|
||||
}
|
||||
if (!(this.path instanceof AST_String)) throw new Error("path must be AST_String");
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
@@ -1263,6 +1392,9 @@ var AST_ExportReferences = DEFNODE("ExportReferences", "properties", {
|
||||
$propdoc: {
|
||||
properties: "[AST_SymbolExport*] array of aliases to export",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.properties, node.properties);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1278,14 +1410,20 @@ var AST_ExportReferences = DEFNODE("ExportReferences", "properties", {
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_Import = DEFNODE("Import", "all default path properties quote", {
|
||||
var AST_Import = DEFNODE("Import", "all default path properties", {
|
||||
$documentation: "An `import` statement",
|
||||
$propdoc: {
|
||||
all: "[AST_SymbolImport?] the imported namespace, or null if not specified",
|
||||
default: "[AST_SymbolImport?] the alias for default `export`, or null if not specified",
|
||||
path: "[string] the path to import module",
|
||||
path: "[AST_String] the path to import module",
|
||||
properties: "[(AST_SymbolImport*)?] array of aliases, or null if not specified",
|
||||
quote: "[string?] the original quote character",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.path.equals(node.path)
|
||||
&& prop_equals(this.all, node.all)
|
||||
&& prop_equals(this.default, node.default)
|
||||
&& !this.properties == !node.properties
|
||||
&& (!this.properties || all_equals(this.properties, node.properties));
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
@@ -1304,16 +1442,12 @@ var AST_Import = DEFNODE("Import", "all default path properties quote", {
|
||||
}
|
||||
if (this.default != null) {
|
||||
if (!(this.default instanceof AST_SymbolImport)) throw new Error("default must be AST_SymbolImport");
|
||||
if (this.default.key !== "") throw new Error("invalid default key: " + this.default.key);
|
||||
if (this.default.key.value !== "") throw new Error("invalid default key: " + this.default.key.value);
|
||||
}
|
||||
if (typeof this.path != "string") throw new Error("path must be string");
|
||||
if (!(this.path instanceof AST_String)) throw new Error("path must be AST_String");
|
||||
if (this.properties != null) this.properties.forEach(function(node) {
|
||||
if (!(node instanceof AST_SymbolImport)) throw new Error("properties must contain AST_SymbolImport");
|
||||
});
|
||||
if (this.quote != null) {
|
||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
||||
if (!/^["']$/.test(this.quote)) throw new Error("invalid quote: " + this.quote);
|
||||
}
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
@@ -1323,6 +1457,10 @@ var AST_DefaultValue = DEFNODE("DefaultValue", "name value", {
|
||||
name: "[AST_Destructured|AST_SymbolDeclaration] name of the variable",
|
||||
value: "[AST_Node] value to assign if variable is `undefined`",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name.equals(node.name)
|
||||
&& this.value.equals(node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1350,6 +1488,11 @@ var AST_Call = DEFNODE("Call", "args expression optional pure terminal", {
|
||||
pure: "[boolean/S] marker for side-effect-free call expression",
|
||||
terminal: "[boolean] whether the chain has ended",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.optional == !node.optional
|
||||
&& this.expression.equals(node.expression)
|
||||
&& all_equals(this.args, node.args);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1376,7 +1519,10 @@ var AST_New = DEFNODE("New", null, {
|
||||
var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
||||
$documentation: "A sequence expression (comma-separated expressions)",
|
||||
$propdoc: {
|
||||
expressions: "[AST_Node*] array of expressions (at least two)"
|
||||
expressions: "[AST_Node*] array of expressions (at least two)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.expressions, node.expressions);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
@@ -1405,6 +1551,11 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression optional property termina
|
||||
property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node",
|
||||
terminal: "[boolean] whether the chain has ended",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.optional == !node.optional
|
||||
&& prop_equals(this.property, node.property)
|
||||
&& this.expression.equals(node.expression);
|
||||
},
|
||||
get_property: function() {
|
||||
var p = this.property;
|
||||
if (p instanceof AST_Constant) return p.value;
|
||||
@@ -1417,8 +1568,11 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression optional property termina
|
||||
},
|
||||
});
|
||||
|
||||
var AST_Dot = DEFNODE("Dot", null, {
|
||||
var AST_Dot = DEFNODE("Dot", "quoted", {
|
||||
$documentation: "A dotted property access expression",
|
||||
$propdoc: {
|
||||
quoted: "[boolean] whether property is transformed from a quoted string",
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1449,6 +1603,9 @@ var AST_Spread = DEFNODE("Spread", "expression", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] expression to be expanded",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1464,7 +1621,11 @@ var AST_Unary = DEFNODE("Unary", "operator expression", {
|
||||
$documentation: "Base class for unary expressions",
|
||||
$propdoc: {
|
||||
operator: "[string] the operator",
|
||||
expression: "[AST_Node] expression that this unary operator applies to"
|
||||
expression: "[AST_Node] expression that this unary operator applies to",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.operator == node.operator
|
||||
&& this.expression.equals(node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
@@ -1494,6 +1655,11 @@ var AST_Binary = DEFNODE("Binary", "operator left right", {
|
||||
operator: "[string] the operator",
|
||||
right: "[AST_Node] right-hand side expression"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.operator == node.operator
|
||||
&& this.left.equals(node.left)
|
||||
&& this.right.equals(node.right);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1515,6 +1681,11 @@ var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative",
|
||||
consequent: "[AST_Node]",
|
||||
alternative: "[AST_Node]"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.condition.equals(node.condition)
|
||||
&& this.consequent.equals(node.consequent)
|
||||
&& this.alternative.equals(node.alternative);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1556,6 +1727,9 @@ var AST_Await = DEFNODE("Await", "expression", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] expression with Promise to resolve on",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1573,6 +1747,10 @@ var AST_Yield = DEFNODE("Yield", "expression nested", {
|
||||
expression: "[AST_Node?] return value for iterator, or null if undefined",
|
||||
nested: "[boolean] whether to iterate over expression as generator",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.nested == !node.nested
|
||||
&& prop_equals(this.expression, node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1595,6 +1773,9 @@ var AST_Array = DEFNODE("Array", "elements", {
|
||||
$propdoc: {
|
||||
elements: "[AST_Node*] array of elements"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.elements, node.elements);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1637,6 +1818,10 @@ var AST_DestructuredArray = DEFNODE("DestructuredArray", "elements", {
|
||||
$propdoc: {
|
||||
elements: "[(AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef)*] array of elements",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.rest, node.rest)
|
||||
&& all_equals(this.elements, node.elements);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1654,6 +1839,10 @@ var AST_DestructuredKeyVal = DEFNODE("DestructuredKeyVal", "key value", {
|
||||
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
||||
value: "[AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef] property value",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.key, node.key)
|
||||
&& this.value.equals(node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1675,6 +1864,10 @@ var AST_DestructuredObject = DEFNODE("DestructuredObject", "properties", {
|
||||
$propdoc: {
|
||||
properties: "[AST_DestructuredKeyVal*] array of properties",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.rest, node.rest)
|
||||
&& all_equals(this.properties, node.properties);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1696,6 +1889,9 @@ var AST_Object = DEFNODE("Object", "properties", {
|
||||
$propdoc: {
|
||||
properties: "[(AST_ObjectProperty|AST_Spread)*] array of properties"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.properties, node.properties);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1719,6 +1915,10 @@ var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
||||
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
||||
value: "[AST_Node] property value. For getters and setters this is an AST_Accessor.",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.key, node.key)
|
||||
&& this.value.equals(node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1773,6 +1973,9 @@ var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
|
||||
scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
|
||||
thedef: "[SymbolDef/S] the definition of this symbol"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.thedef ? this.thedef === node.thedef : this.name == node.name;
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.TYPE == "Symbol") throw new Error("should not instantiate AST_Symbol");
|
||||
if (typeof this.name != "string") throw new Error("name must be string");
|
||||
@@ -1790,10 +1993,14 @@ var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
||||
var AST_SymbolImport = DEFNODE("SymbolImport", "key", {
|
||||
$documentation: "Symbol defined by an `import` statement",
|
||||
$propdoc: {
|
||||
key: "[string] the original `export` name",
|
||||
key: "[AST_String] the original `export` name",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name == node.name
|
||||
&& this.key.equals(node.key);
|
||||
},
|
||||
_validate: function() {
|
||||
if (typeof this.key != "string") throw new Error("key must be string");
|
||||
if (!(this.key instanceof AST_String)) throw new Error("key must be AST_String");
|
||||
},
|
||||
}, AST_SymbolConst);
|
||||
|
||||
@@ -1847,10 +2054,14 @@ var AST_SymbolRef = DEFNODE("SymbolRef", "fixed in_arg redef", {
|
||||
var AST_SymbolExport = DEFNODE("SymbolExport", "alias", {
|
||||
$documentation: "Reference in an `export` statement",
|
||||
$propdoc: {
|
||||
alias: "[string] the `export` alias",
|
||||
alias: "[AST_String] the `export` alias",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name == node.name
|
||||
&& this.alias.equals(node.alias);
|
||||
},
|
||||
_validate: function() {
|
||||
if (typeof this.alias != "string") throw new Error("alias must be string");
|
||||
if (!(this.alias instanceof AST_String)) throw new Error("alias must be AST_String");
|
||||
},
|
||||
}, AST_SymbolRef);
|
||||
|
||||
@@ -1860,6 +2071,7 @@ var AST_LabelRef = DEFNODE("LabelRef", null, {
|
||||
|
||||
var AST_ObjectIdentity = DEFNODE("ObjectIdentity", null, {
|
||||
$documentation: "Base class for `super` & `this`",
|
||||
_equals: return_true,
|
||||
_validate: function() {
|
||||
if (this.TYPE == "ObjectIdentity") throw new Error("should not instantiate AST_ObjectIdentity");
|
||||
},
|
||||
@@ -1894,7 +2106,12 @@ var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
||||
$propdoc: {
|
||||
expressions: "[AST_Node*] the placeholder expressions",
|
||||
strings: "[string*] the raw text segments",
|
||||
tag: "[AST_Node] tag function, or null if absent",
|
||||
tag: "[AST_Node?] tag function, or null if absent",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.tag, node.tag)
|
||||
&& list_equals(this.strings, node.strings)
|
||||
&& all_equals(this.expressions, node.expressions);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
@@ -1919,6 +2136,9 @@ var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
||||
|
||||
var AST_Constant = DEFNODE("Constant", null, {
|
||||
$documentation: "Base class for all constants",
|
||||
_equals: function(node) {
|
||||
return this.value === node.value;
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.TYPE == "Constant") throw new Error("should not instantiate AST_Constant");
|
||||
},
|
||||
@@ -1967,6 +2187,9 @@ var AST_RegExp = DEFNODE("RegExp", "value", {
|
||||
$propdoc: {
|
||||
value: "[RegExp] the actual regexp"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return "" + this.value == "" + node.value;
|
||||
},
|
||||
_validate: function() {
|
||||
if (!(this.value instanceof RegExp)) throw new Error("value must be RegExp");
|
||||
},
|
||||
@@ -1974,6 +2197,7 @@ var AST_RegExp = DEFNODE("RegExp", "value", {
|
||||
|
||||
var AST_Atom = DEFNODE("Atom", null, {
|
||||
$documentation: "Base class for atoms",
|
||||
_equals: return_true,
|
||||
_validate: function() {
|
||||
if (this.TYPE == "Atom") throw new Error("should not instantiate AST_Atom");
|
||||
},
|
||||
|
||||
2184
lib/compress.js
2184
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -76,6 +76,7 @@ function minify(files, options) {
|
||||
annotations: undefined,
|
||||
compress: {},
|
||||
enclose: false,
|
||||
expression: false,
|
||||
ie: false,
|
||||
ie8: false,
|
||||
keep_fargs: false,
|
||||
@@ -98,6 +99,7 @@ function minify(files, options) {
|
||||
if (options.validate) AST_Node.enable_validation();
|
||||
var timings = options.timings && { start: Date.now() };
|
||||
if (options.annotations !== undefined) set_shorthand("annotations", options, [ "compress", "output" ]);
|
||||
if (options.expression) set_shorthand("expression", options, [ "compress", "parse" ]);
|
||||
if (options.ie8) options.ie = options.ie || options.ie8;
|
||||
if (options.ie) set_shorthand("ie", options, [ "compress", "mangle", "output", "rename" ]);
|
||||
if (options.keep_fargs) set_shorthand("keep_fargs", options, [ "compress", "mangle", "rename" ]);
|
||||
@@ -153,13 +155,11 @@ function minify(files, options) {
|
||||
}, options.warnings == "verbose");
|
||||
if (timings) timings.parse = Date.now();
|
||||
var toplevel;
|
||||
if (files instanceof AST_Toplevel) {
|
||||
options.parse = options.parse || {};
|
||||
if (files instanceof AST_Node) {
|
||||
toplevel = files;
|
||||
} else {
|
||||
if (typeof files == "string") {
|
||||
files = [ files ];
|
||||
}
|
||||
options.parse = options.parse || {};
|
||||
if (typeof files == "string") files = [ files ];
|
||||
options.parse.toplevel = null;
|
||||
var source_map_content = options.sourceMap && options.sourceMap.content;
|
||||
if (typeof source_map_content == "string" && source_map_content != "inline") {
|
||||
@@ -171,17 +171,14 @@ function minify(files, options) {
|
||||
options.parse.toplevel = toplevel = parse(files[name], options.parse);
|
||||
if (source_map_content == "inline") {
|
||||
var inlined_content = read_source_map(name, toplevel);
|
||||
if (inlined_content) {
|
||||
options.sourceMap.orig[name] = parse_source_map(inlined_content);
|
||||
}
|
||||
if (inlined_content) options.sourceMap.orig[name] = parse_source_map(inlined_content);
|
||||
} else if (source_map_content) {
|
||||
options.sourceMap.orig[name] = source_map_content;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (quoted_props) {
|
||||
reserve_quoted_keys(toplevel, quoted_props);
|
||||
}
|
||||
if (options.parse.expression) toplevel = toplevel.wrap_expression();
|
||||
if (quoted_props) reserve_quoted_keys(toplevel, quoted_props);
|
||||
[ "enclose", "wrap" ].forEach(function(action) {
|
||||
var option = options[action];
|
||||
if (!option) return;
|
||||
@@ -208,7 +205,9 @@ function minify(files, options) {
|
||||
toplevel.mangle_names(options.mangle);
|
||||
}
|
||||
if (timings) timings.properties = Date.now();
|
||||
if (quoted_props) reserve_quoted_keys(toplevel, quoted_props);
|
||||
if (options.mangle && options.mangle.properties) mangle_properties(toplevel, options.mangle.properties);
|
||||
if (options.parse.expression) toplevel = toplevel.unwrap_expression();
|
||||
if (timings) timings.output = Date.now();
|
||||
var result = {};
|
||||
var output = defaults(options.output, {
|
||||
|
||||
@@ -192,6 +192,19 @@
|
||||
value: from_moz(M.value),
|
||||
});
|
||||
},
|
||||
StaticBlock: function(M) {
|
||||
var start = my_start_token(M);
|
||||
var end = my_end_token(M);
|
||||
return new AST_ClassInit({
|
||||
start: start,
|
||||
end: end,
|
||||
value: new AST_ClassInitBlock({
|
||||
start: start,
|
||||
end: end,
|
||||
body: normalize_directives(M.body.map(from_moz)),
|
||||
}),
|
||||
});
|
||||
},
|
||||
ForOfStatement: function(M) {
|
||||
return new (M.await ? AST_ForAwaitOf : AST_ForOf)({
|
||||
start: my_start_token(M),
|
||||
@@ -303,13 +316,22 @@
|
||||
});
|
||||
},
|
||||
ExportAllDeclaration: function(M) {
|
||||
var alias = M.exported ? read_name(M.exported) : "*";
|
||||
var start = my_start_token(M);
|
||||
var end = my_end_token(M);
|
||||
return new AST_ExportForeign({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
aliases: [ alias ],
|
||||
keys: [ "*" ],
|
||||
path: M.source.value,
|
||||
start: start,
|
||||
end: end,
|
||||
aliases: [ M.exported ? from_moz_alias(M.exported) : new AST_String({
|
||||
start: start,
|
||||
value: "*",
|
||||
end: end,
|
||||
}) ],
|
||||
keys: [ new AST_String({
|
||||
start: start,
|
||||
value: "*",
|
||||
end: end,
|
||||
}) ],
|
||||
path: from_moz(M.source),
|
||||
});
|
||||
},
|
||||
ExportDefaultDeclaration: function(M) {
|
||||
@@ -346,15 +368,15 @@
|
||||
if (M.source) {
|
||||
var aliases = [], keys = [];
|
||||
M.specifiers.forEach(function(prop) {
|
||||
aliases.push(read_name(prop.exported));
|
||||
keys.push(read_name(prop.local));
|
||||
aliases.push(from_moz_alias(prop.exported));
|
||||
keys.push(from_moz_alias(prop.local));
|
||||
});
|
||||
return new AST_ExportForeign({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
aliases: aliases,
|
||||
keys: keys,
|
||||
path: M.source.value,
|
||||
path: from_moz(M.source),
|
||||
});
|
||||
}
|
||||
return new AST_ExportReferences({
|
||||
@@ -362,38 +384,48 @@
|
||||
end: my_end_token(M),
|
||||
properties: M.specifiers.map(function(prop) {
|
||||
var sym = new AST_SymbolExport(from_moz(prop.local));
|
||||
sym.alias = read_name(prop.exported);
|
||||
sym.alias = from_moz_alias(prop.exported);
|
||||
return sym;
|
||||
}),
|
||||
});
|
||||
},
|
||||
ImportDeclaration: function(M) {
|
||||
var start = my_start_token(M);
|
||||
var end = my_end_token(M);
|
||||
var all = null, def = null, props = null;
|
||||
M.specifiers.forEach(function(prop) {
|
||||
var sym = new AST_SymbolImport(from_moz(prop.local));
|
||||
switch (prop.type) {
|
||||
case "ImportDefaultSpecifier":
|
||||
def = sym;
|
||||
def.key = "";
|
||||
def.key = new AST_String({
|
||||
start: start,
|
||||
value: "",
|
||||
end: end,
|
||||
});
|
||||
break;
|
||||
case "ImportNamespaceSpecifier":
|
||||
all = sym;
|
||||
all.key = "*";
|
||||
all.key = new AST_String({
|
||||
start: start,
|
||||
value: "*",
|
||||
end: end,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
sym.key = prop.imported.name || syn.name;
|
||||
sym.key = from_moz_alias(prop.imported);
|
||||
if (!props) props = [];
|
||||
props.push(sym);
|
||||
break;
|
||||
}
|
||||
});
|
||||
return new AST_Import({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
start: start,
|
||||
end: end,
|
||||
all: all,
|
||||
default: def,
|
||||
properties: props,
|
||||
path: M.source.value,
|
||||
path: from_moz(M.source),
|
||||
});
|
||||
},
|
||||
ImportExpression: function(M) {
|
||||
@@ -714,6 +746,10 @@
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_ClassInit, function To_Moz_StaticBlock(M) {
|
||||
return to_moz_scope("StaticBlock", M.value);
|
||||
});
|
||||
|
||||
function To_Moz_ForOfStatement(is_await) {
|
||||
return function(M) {
|
||||
return {
|
||||
@@ -780,38 +816,26 @@
|
||||
});
|
||||
|
||||
def_to_moz(AST_ExportForeign, function To_Moz_ExportAllDeclaration_ExportNamedDeclaration(M) {
|
||||
if (M.keys[0] == "*") return {
|
||||
if (M.keys[0].value == "*") return {
|
||||
type: "ExportAllDeclaration",
|
||||
exported: M.aliases[0] == "*" ? null : {
|
||||
type: "Identifier",
|
||||
name: M.aliases[0],
|
||||
},
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: M.path,
|
||||
},
|
||||
exported: M.aliases[0].value == "*" ? null : to_moz_alias(M.aliases[0]),
|
||||
source: to_moz(M.path),
|
||||
};
|
||||
var specifiers = [];
|
||||
for (var i = 0; i < M.aliases.length; i++) {
|
||||
specifiers.push({
|
||||
specifiers.push(set_moz_loc({
|
||||
start: M.keys[i].start,
|
||||
end: M.aliases[i].end,
|
||||
}, {
|
||||
type: "ExportSpecifier",
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: M.aliases[i],
|
||||
},
|
||||
local: {
|
||||
type: "Identifier",
|
||||
name: M.keys[i],
|
||||
},
|
||||
});
|
||||
local: to_moz_alias(M.keys[i]),
|
||||
exported: to_moz_alias(M.aliases[i]),
|
||||
}));
|
||||
}
|
||||
return {
|
||||
type: "ExportNamedDeclaration",
|
||||
specifiers: specifiers,
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: M.path,
|
||||
},
|
||||
source: to_moz(M.path),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -819,44 +843,41 @@
|
||||
return {
|
||||
type: "ExportNamedDeclaration",
|
||||
specifiers: M.properties.map(function(prop) {
|
||||
return {
|
||||
return set_moz_loc({
|
||||
start: prop.start,
|
||||
end: prop.alias.end,
|
||||
}, {
|
||||
type: "ExportSpecifier",
|
||||
local: to_moz(prop),
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: prop.alias,
|
||||
},
|
||||
};
|
||||
exported: to_moz_alias(prop.alias),
|
||||
});
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) {
|
||||
var specifiers = M.properties ? M.properties.map(function(prop) {
|
||||
return {
|
||||
return set_moz_loc({
|
||||
start: prop.key.start,
|
||||
end: prop.end,
|
||||
}, {
|
||||
type: "ImportSpecifier",
|
||||
local: to_moz(prop),
|
||||
imported: {
|
||||
type: "Identifier",
|
||||
name: prop.key,
|
||||
},
|
||||
};
|
||||
imported: to_moz_alias(prop.key),
|
||||
});
|
||||
}) : [];
|
||||
if (M.all) specifiers.unshift({
|
||||
if (M.all) specifiers.unshift(set_moz_loc(M.all, {
|
||||
type: "ImportNamespaceSpecifier",
|
||||
local: to_moz(M.all),
|
||||
});
|
||||
if (M.default) specifiers.unshift({
|
||||
}));
|
||||
if (M.default) specifiers.unshift(set_moz_loc(M.default, {
|
||||
type: "ImportDefaultSpecifier",
|
||||
local: to_moz(M.default),
|
||||
});
|
||||
}));
|
||||
return {
|
||||
type: "ImportDeclaration",
|
||||
specifiers: specifiers,
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: M.path,
|
||||
},
|
||||
source: to_moz(M.path),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1203,6 +1224,14 @@
|
||||
return node;
|
||||
}
|
||||
|
||||
function from_moz_alias(moz) {
|
||||
return new AST_String({
|
||||
start: my_start_token(moz),
|
||||
value: read_name(moz),
|
||||
end: my_end_token(moz),
|
||||
});
|
||||
}
|
||||
|
||||
AST_Node.from_mozilla_ast = function(node) {
|
||||
var save_stack = FROM_MOZ_STACK;
|
||||
FROM_MOZ_STACK = [];
|
||||
@@ -1254,6 +1283,13 @@
|
||||
return node != null ? node.to_mozilla_ast() : null;
|
||||
}
|
||||
|
||||
function to_moz_alias(alias) {
|
||||
return is_identifier_string(alias.value) ? set_moz_loc(alias, {
|
||||
type: "Identifier",
|
||||
name: alias.value,
|
||||
}) : to_moz(alias);
|
||||
}
|
||||
|
||||
function to_moz_block(node) {
|
||||
return {
|
||||
type: "BlockStatement",
|
||||
|
||||
120
lib/output.js
120
lib/output.js
@@ -55,6 +55,7 @@ function OutputStream(options) {
|
||||
beautify : false,
|
||||
braces : false,
|
||||
comments : false,
|
||||
extendscript : false,
|
||||
galio : false,
|
||||
ie : false,
|
||||
indent_level : 4,
|
||||
@@ -260,6 +261,15 @@ function OutputStream(options) {
|
||||
|
||||
var require_semicolon = makePredicate("( [ + * / - , .");
|
||||
|
||||
function require_space(prev, ch, str) {
|
||||
return is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")
|
||||
|| (ch == "/" && ch == prev)
|
||||
|| ((ch == "+" || ch == "-") && ch == last)
|
||||
|| last == "--" && ch == ">"
|
||||
|| last == "!" && str == "--"
|
||||
|| prev == "/" && (str == "in" || str == "instanceof");
|
||||
}
|
||||
|
||||
var print = options.beautify
|
||||
|| options.comments
|
||||
|| options.max_line_len
|
||||
@@ -312,12 +322,7 @@ function OutputStream(options) {
|
||||
}
|
||||
|
||||
if (might_need_space) {
|
||||
if (is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")
|
||||
|| (ch == "/" && ch == prev)
|
||||
|| ((ch == "+" || ch == "-") && ch == last)
|
||||
|| str == "--" && last == "!"
|
||||
|| str == "in" && prev == "/"
|
||||
|| last == "--" && ch == ">") {
|
||||
if (require_space(prev, ch, str)) {
|
||||
output += " ";
|
||||
current_col++;
|
||||
}
|
||||
@@ -355,14 +360,7 @@ function OutputStream(options) {
|
||||
}
|
||||
}
|
||||
if (might_need_space) {
|
||||
if (is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")
|
||||
|| (ch == "/" && ch == prev)
|
||||
|| ((ch == "+" || ch == "-") && ch == last)
|
||||
|| str == "--" && last == "!"
|
||||
|| str == "in" && prev == "/"
|
||||
|| last == "--" && ch == ">") {
|
||||
output += " ";
|
||||
}
|
||||
if (require_space(prev, ch, str)) output += " ";
|
||||
if (prev != "<" || str != "!") might_need_space = false;
|
||||
}
|
||||
output += str;
|
||||
@@ -409,10 +407,11 @@ function OutputStream(options) {
|
||||
print(";");
|
||||
}
|
||||
|
||||
function with_block(cont) {
|
||||
function with_block(cont, end) {
|
||||
print("{");
|
||||
newline();
|
||||
with_indent(cont);
|
||||
add_mapping(end);
|
||||
indent();
|
||||
print("}");
|
||||
}
|
||||
@@ -702,6 +701,7 @@ function OutputStream(options) {
|
||||
if (p instanceof AST_Class) return true;
|
||||
// (x++)[y]
|
||||
// (typeof x).y
|
||||
// https://github.com/mishoo/UglifyJS/issues/115
|
||||
if (p instanceof AST_PropAccess) return p.expression === this;
|
||||
// (~x)`foo`
|
||||
if (p instanceof AST_Template) return p.tag === this;
|
||||
@@ -877,7 +877,9 @@ function OutputStream(options) {
|
||||
return needs_parens_assign_cond(this, output);
|
||||
});
|
||||
PARENS(AST_Conditional, function(output) {
|
||||
return needs_parens_assign_cond(this, output);
|
||||
return needs_parens_assign_cond(this, output)
|
||||
// https://github.com/mishoo/UglifyJS/issues/1144
|
||||
|| output.option("extendscript") && output.parent() instanceof AST_Conditional;
|
||||
});
|
||||
PARENS(AST_Yield, function(output) {
|
||||
return needs_parens_assign_cond(this, output);
|
||||
@@ -956,7 +958,7 @@ function OutputStream(options) {
|
||||
if (self.body.length > 0) {
|
||||
output.with_block(function() {
|
||||
display_body(self.body, false, output, allow_directives);
|
||||
});
|
||||
}, self.end);
|
||||
} else print_braced_empty(self, output);
|
||||
}
|
||||
DEFPRINT(AST_BlockStatement, function(output) {
|
||||
@@ -1064,6 +1066,14 @@ function OutputStream(options) {
|
||||
}
|
||||
output.semicolon();
|
||||
});
|
||||
function print_alias(alias, output) {
|
||||
var value = alias.value;
|
||||
if (value == "*" || is_identifier_string(value)) {
|
||||
output.print_name(value);
|
||||
} else {
|
||||
output.print_string(value, alias.quote);
|
||||
}
|
||||
}
|
||||
DEFPRINT(AST_ExportForeign, function(output) {
|
||||
var self = this;
|
||||
output.print("export");
|
||||
@@ -1071,7 +1081,7 @@ function OutputStream(options) {
|
||||
var len = self.keys.length;
|
||||
if (len == 0) {
|
||||
print_braced_empty(self, output);
|
||||
} else if (self.keys[0] == "*") {
|
||||
} else if (self.keys[0].value == "*") {
|
||||
print_entry(0);
|
||||
} else output.with_block(function() {
|
||||
output.indent();
|
||||
@@ -1083,22 +1093,22 @@ function OutputStream(options) {
|
||||
print_entry(i);
|
||||
}
|
||||
output.newline();
|
||||
});
|
||||
}, self.end);
|
||||
output.space();
|
||||
output.print("from");
|
||||
output.space();
|
||||
output.print_string(self.path, self.quote);
|
||||
self.path.print(output);
|
||||
output.semicolon();
|
||||
|
||||
function print_entry(index) {
|
||||
var alias = self.aliases[index];
|
||||
var key = self.keys[index];
|
||||
output.print_name(key);
|
||||
if (alias != key) {
|
||||
print_alias(key, output);
|
||||
if (alias.value != key.value) {
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
output.print_name(alias);
|
||||
print_alias(alias, output);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1127,7 +1137,7 @@ function OutputStream(options) {
|
||||
output.print("from");
|
||||
output.space();
|
||||
}
|
||||
output.print_string(self.path, self.quote);
|
||||
self.path.print(output);
|
||||
output.semicolon();
|
||||
});
|
||||
|
||||
@@ -1257,6 +1267,11 @@ function OutputStream(options) {
|
||||
}
|
||||
print_method(self, output);
|
||||
});
|
||||
DEFPRINT(AST_ClassInit, function(output) {
|
||||
output.print("static");
|
||||
output.space();
|
||||
print_braced(this.value, output);
|
||||
});
|
||||
|
||||
/* -----[ jumps ]----- */
|
||||
function print_jump(kind, prop) {
|
||||
@@ -1342,7 +1357,7 @@ function OutputStream(options) {
|
||||
if (i < last && branch.body.length > 0)
|
||||
output.newline();
|
||||
});
|
||||
});
|
||||
}, self.end);
|
||||
});
|
||||
function print_branch_body(self, output) {
|
||||
output.newline();
|
||||
@@ -1462,14 +1477,12 @@ function OutputStream(options) {
|
||||
output.print("/*@__PURE__*/");
|
||||
}
|
||||
function print_call_args(self, output) {
|
||||
if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
|
||||
output.add_mapping(self.start);
|
||||
}
|
||||
output.with_parens(function() {
|
||||
self.args.forEach(function(expr, i) {
|
||||
if (i) output.comma();
|
||||
expr.print(output);
|
||||
});
|
||||
output.add_mapping(self.end);
|
||||
});
|
||||
}
|
||||
DEFPRINT(AST_Call, function(output) {
|
||||
@@ -1504,11 +1517,12 @@ function OutputStream(options) {
|
||||
var expr = self.expression;
|
||||
expr.print(output);
|
||||
var prop = self.property;
|
||||
if (output.option("ie") && RESERVED_WORDS[prop]) {
|
||||
output.print(self.optional ? "?.[" : "[");
|
||||
output.add_mapping(self.end);
|
||||
output.print_string(prop);
|
||||
output.print("]");
|
||||
if (output.option("ie") && RESERVED_WORDS[prop] || self.quoted && output.option("keep_quoted_props")) {
|
||||
if (self.optional) output.print("?.");
|
||||
output.with_square(function() {
|
||||
output.add_mapping(self.end);
|
||||
output.print_string(prop);
|
||||
});
|
||||
} else {
|
||||
if (expr instanceof AST_Number && !/[ex.)]/i.test(output.last())) output.print(".");
|
||||
output.print(self.optional ? "?." : ".");
|
||||
@@ -1520,9 +1534,10 @@ function OutputStream(options) {
|
||||
DEFPRINT(AST_Sub, function(output) {
|
||||
var self = this;
|
||||
self.expression.print(output);
|
||||
output.print(self.optional ? "?.[" : "[");
|
||||
self.property.print(output);
|
||||
output.print("]");
|
||||
if (self.optional) output.print("?.");
|
||||
output.with_square(function() {
|
||||
self.property.print(output);
|
||||
});
|
||||
});
|
||||
DEFPRINT(AST_Spread, function(output) {
|
||||
output.print("...");
|
||||
@@ -1541,8 +1556,10 @@ function OutputStream(options) {
|
||||
exp.print(output);
|
||||
});
|
||||
DEFPRINT(AST_UnaryPostfix, function(output) {
|
||||
this.expression.print(output);
|
||||
output.print(this.operator);
|
||||
var self = this;
|
||||
self.expression.print(output);
|
||||
output.add_mapping(self.end);
|
||||
output.print(self.operator);
|
||||
});
|
||||
DEFPRINT(AST_Binary, function(output) {
|
||||
var self = this;
|
||||
@@ -1635,7 +1652,8 @@ function OutputStream(options) {
|
||||
value.print(output);
|
||||
});
|
||||
DEFPRINT(AST_DestructuredObject, function(output) {
|
||||
var props = this.properties, len = props.length, rest = this.rest;
|
||||
var self = this;
|
||||
var props = self.properties, len = props.length, rest = self.rest;
|
||||
if (len || rest) output.with_block(function() {
|
||||
props.forEach(function(prop, i) {
|
||||
if (i) {
|
||||
@@ -1655,8 +1673,8 @@ function OutputStream(options) {
|
||||
rest.print(output);
|
||||
}
|
||||
output.newline();
|
||||
});
|
||||
else print_braced_empty(this, output);
|
||||
}, self.end);
|
||||
else print_braced_empty(self, output);
|
||||
});
|
||||
function print_properties(self, output, no_comma) {
|
||||
var props = self.properties;
|
||||
@@ -1670,7 +1688,7 @@ function OutputStream(options) {
|
||||
prop.print(output);
|
||||
});
|
||||
output.newline();
|
||||
});
|
||||
}, self.end);
|
||||
else print_braced_empty(self, output);
|
||||
}
|
||||
DEFPRINT(AST_Object, function(output) {
|
||||
@@ -1732,19 +1750,19 @@ function OutputStream(options) {
|
||||
var name = get_symbol_name(self);
|
||||
output.print_name(name);
|
||||
var alias = self.alias;
|
||||
if (alias != name) {
|
||||
if (alias.value != name) {
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
output.print_name(alias);
|
||||
print_alias(alias, output);
|
||||
}
|
||||
});
|
||||
DEFPRINT(AST_SymbolImport, function(output) {
|
||||
var self = this;
|
||||
var name = get_symbol_name(self);
|
||||
var key = self.key;
|
||||
if (key && key != name) {
|
||||
output.print_name(key);
|
||||
if (key.value && key.value != name) {
|
||||
print_alias(key, output);
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
@@ -1814,9 +1832,6 @@ function OutputStream(options) {
|
||||
case "\u2029": return "\\u2029";
|
||||
}
|
||||
}));
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === this)
|
||||
output.print(" ");
|
||||
});
|
||||
|
||||
function force_statement(stat, output) {
|
||||
@@ -1883,7 +1898,7 @@ function OutputStream(options) {
|
||||
output.indent();
|
||||
stmt.print(output);
|
||||
output.newline();
|
||||
});
|
||||
}, stmt.end);
|
||||
}
|
||||
|
||||
/* -----[ source map generators ]----- */
|
||||
@@ -1906,22 +1921,27 @@ function OutputStream(options) {
|
||||
// or if we should add even more.
|
||||
DEFMAP([
|
||||
AST_Array,
|
||||
AST_Await,
|
||||
AST_BlockStatement,
|
||||
AST_Catch,
|
||||
AST_Constant,
|
||||
AST_Debugger,
|
||||
AST_Definitions,
|
||||
AST_Destructured,
|
||||
AST_Directive,
|
||||
AST_Finally,
|
||||
AST_Jump,
|
||||
AST_Lambda,
|
||||
AST_New,
|
||||
AST_Object,
|
||||
AST_Spread,
|
||||
AST_StatementWithBody,
|
||||
AST_Symbol,
|
||||
AST_Switch,
|
||||
AST_SwitchBranch,
|
||||
AST_Try,
|
||||
AST_UnaryPrefix,
|
||||
AST_Yield,
|
||||
], function(output) {
|
||||
output.add_mapping(this.start);
|
||||
});
|
||||
|
||||
140
lib/parse.js
140
lib/parse.js
@@ -552,16 +552,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
|
||||
function handle_dot() {
|
||||
next();
|
||||
var ch = peek();
|
||||
if (ch == ".") {
|
||||
var op = ".";
|
||||
do {
|
||||
op += ".";
|
||||
next();
|
||||
} while (peek() == ".");
|
||||
return token("operator", op);
|
||||
}
|
||||
return is_digit(ch.charCodeAt(0)) ? read_num(".") : token("punc", ".");
|
||||
if (looking_at("..")) return token("operator", "." + next() + next());
|
||||
return is_digit(peek().charCodeAt(0)) ? read_num(".") : token("punc", ".");
|
||||
}
|
||||
|
||||
function read_word() {
|
||||
@@ -815,7 +807,7 @@ function parse($TEXT, options) {
|
||||
}
|
||||
}
|
||||
|
||||
var statement = embed_tokens(function() {
|
||||
var statement = embed_tokens(function(toplevel) {
|
||||
handle_regexp();
|
||||
switch (S.token.type) {
|
||||
case "string":
|
||||
@@ -854,15 +846,15 @@ function parse($TEXT, options) {
|
||||
if (S.in_async) return simple_statement();
|
||||
break;
|
||||
case "export":
|
||||
if (!toplevel && options.module !== "") unexpected();
|
||||
next();
|
||||
return export_();
|
||||
case "import":
|
||||
var token = peek();
|
||||
if (!(token.type == "punc" && /^[(.]$/.test(token.value))) {
|
||||
next();
|
||||
return import_();
|
||||
}
|
||||
break;
|
||||
if (token.type == "punc" && /^[(.]$/.test(token.value)) break;
|
||||
if (!toplevel && options.module !== "") unexpected();
|
||||
next();
|
||||
return import_();
|
||||
case "let":
|
||||
if (is_vardefs()) {
|
||||
next();
|
||||
@@ -1064,13 +1056,13 @@ function parse($TEXT, options) {
|
||||
return stat;
|
||||
}
|
||||
|
||||
function has_modifier(name) {
|
||||
function has_modifier(name, no_nlb) {
|
||||
if (!is("name", name)) return;
|
||||
var token = peek();
|
||||
if (!token) return;
|
||||
if (is_token(token, "operator", "=")) return;
|
||||
if (token.type == "punc" && /^[(;}]$/.test(token.value)) return;
|
||||
if (has_newline_before(token)) return;
|
||||
if (no_nlb && has_newline_before(token)) return;
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -1100,7 +1092,7 @@ function parse($TEXT, options) {
|
||||
}
|
||||
var start = S.token;
|
||||
var fixed = !!has_modifier("static");
|
||||
var async = has_modifier("async");
|
||||
var async = has_modifier("async", true);
|
||||
if (is("operator", "*")) {
|
||||
next();
|
||||
var internal = is("name") && /^#/.test(S.token.value);
|
||||
@@ -1119,6 +1111,18 @@ function parse($TEXT, options) {
|
||||
}));
|
||||
continue;
|
||||
}
|
||||
if (fixed && is("punc", "{")) {
|
||||
props.push(new AST_ClassInit({
|
||||
start: start,
|
||||
value: new AST_ClassInitBlock({
|
||||
start: start,
|
||||
body: block_(),
|
||||
end: prev(),
|
||||
}),
|
||||
end: prev(),
|
||||
}));
|
||||
continue;
|
||||
}
|
||||
var internal = is("name") && /^#/.test(S.token.value);
|
||||
var key = as_property_key();
|
||||
if (is("punc", "(")) {
|
||||
@@ -1335,9 +1339,11 @@ function parse($TEXT, options) {
|
||||
var loop = S.in_loop;
|
||||
var labels = S.labels;
|
||||
++S.in_function;
|
||||
S.input.push_directives_stack();
|
||||
S.in_loop = 0;
|
||||
S.labels = [];
|
||||
if (is("punc", "{")) {
|
||||
S.in_directives = true;
|
||||
body = block_();
|
||||
value = null;
|
||||
} else {
|
||||
@@ -1345,6 +1351,8 @@ function parse($TEXT, options) {
|
||||
handle_regexp();
|
||||
value = maybe_assign();
|
||||
}
|
||||
var is_strict = S.input.has_directive("use strict");
|
||||
S.input.pop_directives_stack();
|
||||
--S.in_function;
|
||||
S.in_loop = loop;
|
||||
S.labels = labels;
|
||||
@@ -1358,7 +1366,7 @@ function parse($TEXT, options) {
|
||||
value: value,
|
||||
end: prev(),
|
||||
});
|
||||
if (S.input.has_directive("use strict")) node.each_argname(strict_verify_symbol);
|
||||
if (is_strict) node.each_argname(strict_verify_symbol);
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -1426,28 +1434,41 @@ function parse($TEXT, options) {
|
||||
}
|
||||
|
||||
function is_alias() {
|
||||
return is("name") || is_identifier_string(S.token.value);
|
||||
return is("name") || is("string") || is_identifier_string(S.token.value);
|
||||
}
|
||||
|
||||
function make_string(token) {
|
||||
return new AST_String({
|
||||
start: token,
|
||||
quote: token.quote,
|
||||
value: token.value,
|
||||
end: token,
|
||||
});
|
||||
}
|
||||
|
||||
function as_path() {
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return make_string(path);
|
||||
}
|
||||
|
||||
function export_() {
|
||||
if (is("operator", "*")) {
|
||||
var key = S.token;
|
||||
var alias = key;
|
||||
next();
|
||||
var alias = "*";
|
||||
if (is("name", "as")) {
|
||||
next();
|
||||
if (!is_alias()) expect_token("name");
|
||||
alias = S.token.value;
|
||||
alias = S.token;
|
||||
next();
|
||||
}
|
||||
expect_token("name", "from");
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return new AST_ExportForeign({
|
||||
aliases: [ alias ],
|
||||
keys: [ "*" ],
|
||||
path: path.value,
|
||||
quote: path.quote,
|
||||
aliases: [ make_string(alias) ],
|
||||
keys: [ make_string(key) ],
|
||||
path: as_path(),
|
||||
});
|
||||
}
|
||||
if (is("punc", "{")) {
|
||||
@@ -1461,26 +1482,20 @@ function parse($TEXT, options) {
|
||||
if (is("name", "as")) {
|
||||
next();
|
||||
if (!is_alias()) expect_token("name");
|
||||
aliases.push(S.token.value);
|
||||
aliases.push(S.token);
|
||||
next();
|
||||
} else {
|
||||
aliases.push(key.value);
|
||||
aliases.push(key);
|
||||
}
|
||||
if (!is("punc", "}")) expect(",");
|
||||
}
|
||||
expect("}");
|
||||
if (is("name", "from")) {
|
||||
next();
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return new AST_ExportForeign({
|
||||
aliases: aliases,
|
||||
keys: keys.map(function(token) {
|
||||
return token.value;
|
||||
}),
|
||||
path: path.value,
|
||||
quote: path.quote,
|
||||
aliases: aliases.map(make_string),
|
||||
keys: keys.map(make_string),
|
||||
path: as_path(),
|
||||
});
|
||||
}
|
||||
semicolon();
|
||||
@@ -1488,7 +1503,7 @@ function parse($TEXT, options) {
|
||||
properties: keys.map(function(token, index) {
|
||||
if (!is_token(token, "name")) token_error(token, "Name expected");
|
||||
var sym = _make_symbol(AST_SymbolExport, token);
|
||||
sym.alias = aliases[index];
|
||||
sym.alias = make_string(aliases[index]);
|
||||
return sym;
|
||||
}),
|
||||
});
|
||||
@@ -1578,26 +1593,42 @@ function parse($TEXT, options) {
|
||||
var all = null;
|
||||
var def = as_symbol(AST_SymbolImport, true);
|
||||
var props = null;
|
||||
if (def ? (def.key = "", is("punc", ",") && next()) : !is("string")) {
|
||||
var cont;
|
||||
if (def) {
|
||||
def.key = new AST_String({
|
||||
start: def.start,
|
||||
value: "",
|
||||
end: def.end,
|
||||
});
|
||||
if (cont = is("punc", ",")) next();
|
||||
} else {
|
||||
cont = !is("string");
|
||||
}
|
||||
if (cont) {
|
||||
if (is("operator", "*")) {
|
||||
var key = S.token;
|
||||
next();
|
||||
expect_token("name", "as");
|
||||
all = as_symbol(AST_SymbolImport);
|
||||
all.key = "*";
|
||||
all.key = make_string(key);
|
||||
} else {
|
||||
expect("{");
|
||||
props = [];
|
||||
while (is_alias()) {
|
||||
var alias;
|
||||
if (is_token(peek(), "name", "as")) {
|
||||
var key = S.token.value;
|
||||
var key = S.token;
|
||||
next();
|
||||
next();
|
||||
alias = as_symbol(AST_SymbolImport);
|
||||
alias.key = key;
|
||||
alias.key = make_string(key);
|
||||
} else {
|
||||
alias = as_symbol(AST_SymbolImport);
|
||||
alias.key = alias.name;
|
||||
alias.key = new AST_String({
|
||||
start: alias.start,
|
||||
value: alias.name,
|
||||
end: alias.end,
|
||||
});
|
||||
}
|
||||
props.push(alias);
|
||||
if (!is("punc", "}")) expect(",");
|
||||
@@ -1606,15 +1637,11 @@ function parse($TEXT, options) {
|
||||
}
|
||||
}
|
||||
if (all || def || props) expect_token("name", "from");
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return new AST_Import({
|
||||
all: all,
|
||||
default: def,
|
||||
path: path.value,
|
||||
path: as_path(),
|
||||
properties: props,
|
||||
quote: path.quote,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1792,7 +1819,7 @@ function parse($TEXT, options) {
|
||||
ret = new AST_BigInt({ value: value });
|
||||
break;
|
||||
case "string":
|
||||
ret = new AST_String({ value : value, quote : tok.quote });
|
||||
ret = new AST_String({ value: value, quote: tok.quote });
|
||||
break;
|
||||
case "regexp":
|
||||
ret = new AST_RegExp({ value: value });
|
||||
@@ -2541,10 +2568,13 @@ function parse($TEXT, options) {
|
||||
return function() {
|
||||
var start = S.token;
|
||||
var body = [];
|
||||
if (options.module) S.input.add_directive("use strict");
|
||||
if (options.module) {
|
||||
S.in_async = true;
|
||||
S.input.add_directive("use strict");
|
||||
}
|
||||
S.input.push_directives_stack();
|
||||
while (!is("eof"))
|
||||
body.push(statement());
|
||||
body.push(statement(true));
|
||||
S.input.pop_directives_stack();
|
||||
var end = prev() || start;
|
||||
var toplevel = options.toplevel;
|
||||
|
||||
@@ -43,10 +43,11 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
var builtins = function() {
|
||||
function get_builtins() {
|
||||
var names = new Dictionary();
|
||||
// NaN will be included due to Number.NaN
|
||||
// constants
|
||||
[
|
||||
"NaN",
|
||||
"null",
|
||||
"true",
|
||||
"false",
|
||||
@@ -54,35 +55,79 @@ var builtins = function() {
|
||||
"-Infinity",
|
||||
"undefined",
|
||||
].forEach(add);
|
||||
// global functions
|
||||
[
|
||||
Array,
|
||||
Boolean,
|
||||
Date,
|
||||
Error,
|
||||
Function,
|
||||
Math,
|
||||
Number,
|
||||
Object,
|
||||
RegExp,
|
||||
String,
|
||||
].forEach(function(ctor) {
|
||||
"encodeURI",
|
||||
"encodeURIComponent",
|
||||
"escape",
|
||||
"eval",
|
||||
"decodeURI",
|
||||
"decodeURIComponent",
|
||||
"isFinite",
|
||||
"isNaN",
|
||||
"parseFloat",
|
||||
"parseInt",
|
||||
"unescape",
|
||||
].forEach(add);
|
||||
// global constructors & objects
|
||||
var global = Function("return this")();
|
||||
[
|
||||
"Array",
|
||||
"ArrayBuffer",
|
||||
"Atomics",
|
||||
"BigInt",
|
||||
"Boolean",
|
||||
"console",
|
||||
"DataView",
|
||||
"Date",
|
||||
"Error",
|
||||
"Function",
|
||||
"Int8Array",
|
||||
"Intl",
|
||||
"JSON",
|
||||
"Map",
|
||||
"Math",
|
||||
"Number",
|
||||
"Object",
|
||||
"Promise",
|
||||
"Proxy",
|
||||
"Reflect",
|
||||
"RegExp",
|
||||
"Set",
|
||||
"String",
|
||||
"Symbol",
|
||||
"WebAssembly",
|
||||
].forEach(function(name) {
|
||||
add(name);
|
||||
var ctor = global[name];
|
||||
if (!ctor) return;
|
||||
Object.getOwnPropertyNames(ctor).map(add);
|
||||
if (ctor.prototype) {
|
||||
if (typeof ctor != "function") return;
|
||||
if (ctor.__proto__) Object.getOwnPropertyNames(ctor.__proto__).map(add);
|
||||
if (ctor.prototype) Object.getOwnPropertyNames(ctor.prototype).map(add);
|
||||
try {
|
||||
Object.getOwnPropertyNames(new ctor()).map(add);
|
||||
Object.getOwnPropertyNames(ctor.prototype).map(add);
|
||||
} catch (e) {
|
||||
try {
|
||||
Object.getOwnPropertyNames(ctor()).map(add);
|
||||
} catch (e) {}
|
||||
}
|
||||
});
|
||||
return names;
|
||||
return (get_builtins = function() {
|
||||
return names.clone();
|
||||
})();
|
||||
|
||||
function add(name) {
|
||||
names.set(name, true);
|
||||
}
|
||||
}();
|
||||
}
|
||||
|
||||
function reserve_quoted_keys(ast, reserved) {
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_ClassProperty) {
|
||||
if (node.start && node.start.quote) add(node.key);
|
||||
} else if (node instanceof AST_Dot) {
|
||||
if (node.quoted) add(node.property);
|
||||
} else if (node instanceof AST_ObjectProperty) {
|
||||
if (node.start && node.start.quote) add(node.key);
|
||||
} else if (node instanceof AST_Sub) {
|
||||
@@ -116,7 +161,7 @@ function mangle_properties(ast, options) {
|
||||
reserved: null,
|
||||
}, true);
|
||||
|
||||
var reserved = options.builtins ? new Dictionary() : builtins.clone();
|
||||
var reserved = options.builtins ? new Dictionary() : get_builtins();
|
||||
if (Array.isArray(options.reserved)) options.reserved.forEach(function(name) {
|
||||
reserved.set(name, true);
|
||||
});
|
||||
@@ -217,8 +262,14 @@ function mangle_properties(ast, options) {
|
||||
}
|
||||
|
||||
function should_mangle(name) {
|
||||
if (reserved.has(name)) return false;
|
||||
if (regex && !regex.test(name)) return false;
|
||||
if (reserved.has(name)) {
|
||||
AST_Node.info("Preserving reserved property {this}", name);
|
||||
return false;
|
||||
}
|
||||
if (regex && !regex.test(name)) {
|
||||
AST_Node.info("Preserving excluded property {this}", name);
|
||||
return false;
|
||||
}
|
||||
return cache.has(name) || names_to_mangle.has(name);
|
||||
}
|
||||
|
||||
@@ -243,6 +294,10 @@ function mangle_properties(ast, options) {
|
||||
if (/^#/.test(name)) mangled = "#" + mangled;
|
||||
cache.set(name, mangled);
|
||||
}
|
||||
AST_Node.info("Mapping property {name} to {mangled}", {
|
||||
mangled: mangled,
|
||||
name: name,
|
||||
});
|
||||
return mangled;
|
||||
}
|
||||
|
||||
|
||||
16
lib/scope.js
16
lib/scope.js
@@ -286,7 +286,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
// ensure mangling works if `catch` reuses a scope variable
|
||||
var redef = def.redefined();
|
||||
if (redef) for (var s = node.scope; s; s = s.parent_scope) {
|
||||
push_uniq(s.enclosed, redef);
|
||||
if (!push_uniq(s.enclosed, redef)) break;
|
||||
if (s === redef.scope) break;
|
||||
}
|
||||
} else if (node instanceof AST_SymbolConst) {
|
||||
@@ -369,8 +369,9 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
// pass 3: fix up any scoping issue with IE8
|
||||
if (options.ie) self.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_SymbolCatch) {
|
||||
var scope = node.thedef.defun;
|
||||
if (scope.name instanceof AST_SymbolLambda && scope.name.name == node.name) {
|
||||
var def = node.thedef;
|
||||
var scope = def.defun;
|
||||
if (def.name != "arguments" && scope.name instanceof AST_SymbolLambda && scope.name.name == def.name) {
|
||||
scope = scope.parent_scope.resolve();
|
||||
}
|
||||
redefine(node, scope);
|
||||
@@ -480,7 +481,7 @@ AST_Lambda.DEFMETHOD("init_vars", function(parent_scope) {
|
||||
AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
||||
var def = this.definition();
|
||||
for (var s = this.scope; s; s = s.parent_scope) {
|
||||
push_uniq(s.enclosed, def);
|
||||
if (!push_uniq(s.enclosed, def)) break;
|
||||
if (!options) {
|
||||
s._var_names = undefined;
|
||||
} else {
|
||||
@@ -704,7 +705,12 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
||||
}
|
||||
redefined.push(def);
|
||||
def.references.forEach(reference);
|
||||
if (sym instanceof AST_SymbolCatch || sym instanceof AST_SymbolConst) reference(sym);
|
||||
if (sym instanceof AST_SymbolCatch || sym instanceof AST_SymbolConst) {
|
||||
reference(sym);
|
||||
def.redefined = function() {
|
||||
return redef;
|
||||
};
|
||||
}
|
||||
return true;
|
||||
|
||||
function reference(sym) {
|
||||
|
||||
@@ -127,8 +127,10 @@ function push_uniq(array, el) {
|
||||
|
||||
function string_template(text, props) {
|
||||
return text.replace(/\{([^{}]+)\}/g, function(str, p) {
|
||||
var value = props[p];
|
||||
return value instanceof AST_Node ? value.print_to_string() : value;
|
||||
var value = p == "this" ? props : props[p];
|
||||
if (value instanceof AST_Node) return value.print_to_string();
|
||||
if (value instanceof AST_Token) return value.file + ":" + value.line + "," + value.col;
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.16.0",
|
||||
"version": "3.17.1",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
@@ -23,7 +23,7 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"devDependencies": {
|
||||
"acorn": "~8.2.1",
|
||||
"acorn": "~8.7.1",
|
||||
"semver": "~6.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -60,8 +60,9 @@ function log() {
|
||||
console.log("%s", tmpl.apply(null, arguments));
|
||||
}
|
||||
|
||||
function make_code(ast, options) {
|
||||
function make_code(ast, options, expression) {
|
||||
var stream = U.OutputStream(options);
|
||||
if (expression) ast = ast.clone(true).unwrap_expression();
|
||||
ast.print(stream);
|
||||
return stream.get();
|
||||
}
|
||||
@@ -69,7 +70,7 @@ function make_code(ast, options) {
|
||||
function parse_test(file) {
|
||||
var script = fs.readFileSync(file, "utf8");
|
||||
try {
|
||||
var ast = U.parse(script, { filename: file });
|
||||
var ast = U.parse(script, { filename: file, module: "" });
|
||||
} catch (e) {
|
||||
console.error("Caught error while parsing tests in " + file);
|
||||
console.error(e);
|
||||
@@ -178,9 +179,18 @@ function parse_test(file) {
|
||||
|
||||
// Try to reminify original input with standard options
|
||||
// to see if it matches expect_stdout.
|
||||
function reminify(orig_options, input_code, input_formatted, stdout) {
|
||||
function reminify(expression, orig_options, input_code, input_formatted, stdout) {
|
||||
for (var i = 0; i < minify_options.length; i++) {
|
||||
var options = JSON.parse(minify_options[i]);
|
||||
if (expression) {
|
||||
if (!options.parse || typeof options.parse != "object") options.parse = {};
|
||||
options.parse.expression = true;
|
||||
if (options.compress == null) options.compress = {};
|
||||
if (options.compress) {
|
||||
if (typeof options.compress != "object") options.compress = {};
|
||||
options.compress.expression = true;
|
||||
}
|
||||
}
|
||||
[
|
||||
"keep_fargs",
|
||||
"keep_fnames",
|
||||
@@ -210,7 +220,7 @@ function reminify(orig_options, input_code, input_formatted, stdout) {
|
||||
} else {
|
||||
var toplevel = sandbox.has_toplevel(options);
|
||||
var expected = stdout[toplevel ? 1 : 0];
|
||||
var actual = sandbox.run_code(result.code, toplevel);
|
||||
var actual = run_code(expression, result.code, toplevel);
|
||||
if (typeof expected != "string" && typeof actual != "string" && expected.name == actual.name) {
|
||||
actual = expected;
|
||||
}
|
||||
@@ -245,18 +255,23 @@ function reminify(orig_options, input_code, input_formatted, stdout) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function run_code(expression, code, toplevel) {
|
||||
return sandbox.run_code(expression ? "console.log(" + code + ");" : code, toplevel);
|
||||
}
|
||||
|
||||
function test_case(test) {
|
||||
log(" Running test [{name}]", { name: test.name });
|
||||
U.AST_Node.enable_validation();
|
||||
var output_options = test.beautify || {};
|
||||
var expect;
|
||||
if (test.expect) {
|
||||
expect = make_code(to_toplevel(test.expect, test.mangle), output_options);
|
||||
expect = to_toplevel(test.expect, test.mangle, test.expression);
|
||||
expect = make_code(expect, output_options, test.expression);
|
||||
} else {
|
||||
expect = test.expect_exact;
|
||||
}
|
||||
var input = to_toplevel(test.input, test.mangle);
|
||||
var input_code = make_code(input);
|
||||
var input = to_toplevel(test.input, test.mangle, test.expression);
|
||||
var input_code = make_code(input, {}, test.expression);
|
||||
var input_formatted = make_code(test.input, {
|
||||
annotations: true,
|
||||
beautify: true,
|
||||
@@ -266,7 +281,7 @@ function test_case(test) {
|
||||
});
|
||||
try {
|
||||
input.validate_ast();
|
||||
U.parse(input_code);
|
||||
U.parse(input_code, { expression: test.expression });
|
||||
} catch (ex) {
|
||||
log([
|
||||
"!!! Cannot parse input",
|
||||
@@ -292,8 +307,9 @@ function test_case(test) {
|
||||
warnings_emitted.push(text);
|
||||
}, /"INFO: /.test(expected_warnings));
|
||||
}
|
||||
var quoted_props;
|
||||
if (test.mangle && test.mangle.properties && test.mangle.properties.keep_quoted) {
|
||||
var quoted_props = test.mangle.properties.reserved;
|
||||
quoted_props = test.mangle.properties.reserved;
|
||||
if (!Array.isArray(quoted_props)) quoted_props = [];
|
||||
test.mangle.properties.reserved = quoted_props;
|
||||
U.reserve_quoted_keys(input, quoted_props);
|
||||
@@ -308,9 +324,10 @@ function test_case(test) {
|
||||
if (test.mangle) {
|
||||
output.compute_char_frequency(test.mangle);
|
||||
output.mangle_names(test.mangle);
|
||||
if (quoted_props) U.reserve_quoted_keys(input, quoted_props);
|
||||
if (test.mangle.properties) U.mangle_properties(output, test.mangle.properties);
|
||||
}
|
||||
var output_code = make_code(output, output_options);
|
||||
var output_code = make_code(output, output_options, test.expression);
|
||||
U.AST_Node.log_function();
|
||||
if (expect != output_code) {
|
||||
log([
|
||||
@@ -333,7 +350,7 @@ function test_case(test) {
|
||||
// expect == output
|
||||
try {
|
||||
output.validate_ast();
|
||||
U.parse(output_code);
|
||||
U.parse(output_code, { expression: test.expression });
|
||||
} catch (ex) {
|
||||
log([
|
||||
"!!! Test matched expected result but cannot parse output",
|
||||
@@ -377,7 +394,7 @@ function test_case(test) {
|
||||
}
|
||||
}
|
||||
if (test.expect_stdout && (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
||||
var stdout = [ sandbox.run_code(input_code), sandbox.run_code(input_code, true) ];
|
||||
var stdout = [ run_code(test.expression, input_code), run_code(test.expression, input_code, true) ];
|
||||
var toplevel = sandbox.has_toplevel({
|
||||
compress: test.options,
|
||||
mangle: test.mangle
|
||||
@@ -406,7 +423,7 @@ function test_case(test) {
|
||||
});
|
||||
return false;
|
||||
}
|
||||
actual = sandbox.run_code(output_code, toplevel);
|
||||
actual = run_code(test.expression, output_code, toplevel);
|
||||
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
||||
log([
|
||||
"!!! failed",
|
||||
@@ -427,7 +444,7 @@ function test_case(test) {
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!reminify(test.options, input_code, input_formatted, stdout)) {
|
||||
if (!reminify(test.expression, test.options, input_code, input_formatted, stdout)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -438,20 +455,30 @@ function tmpl() {
|
||||
return U.string_template.apply(null, arguments);
|
||||
}
|
||||
|
||||
function to_toplevel(input, mangle_options) {
|
||||
function to_toplevel(input, mangle_options, expression) {
|
||||
if (!(input instanceof U.AST_BlockStatement)) throw new Error("Unsupported input syntax");
|
||||
var directive = true;
|
||||
var offset = input.start.line;
|
||||
var tokens = [];
|
||||
var toplevel = new U.AST_Toplevel(input.transform(new U.TreeTransformer(function(node) {
|
||||
input.walk(new U.TreeWalker(function(node) {
|
||||
if (U.push_uniq(tokens, node.start)) node.start.line -= offset;
|
||||
if (!directive || node === input) return;
|
||||
if (node instanceof U.AST_SimpleStatement && node.body instanceof U.AST_String) {
|
||||
return new U.AST_Directive(node.body);
|
||||
} else {
|
||||
if (U.push_uniq(tokens, node.end)) node.end.line -= offset;
|
||||
}));
|
||||
var toplevel;
|
||||
if (!expression) {
|
||||
var directive = true;
|
||||
toplevel = new U.AST_Toplevel(input.transform(new U.TreeTransformer(function(node) {
|
||||
if (!directive) return node;
|
||||
if (node === input) return;
|
||||
if (node instanceof U.AST_SimpleStatement && node.body instanceof U.AST_String) {
|
||||
return new U.AST_Directive(node.body);
|
||||
}
|
||||
directive = false;
|
||||
}
|
||||
})));
|
||||
})));
|
||||
} else if (input.body.length == 1) {
|
||||
toplevel = input.body[0].wrap_expression();
|
||||
} else {
|
||||
throw new Error("Invalid expression");
|
||||
}
|
||||
toplevel.figure_out_scope(mangle_options);
|
||||
return toplevel;
|
||||
}
|
||||
|
||||
@@ -668,6 +668,28 @@ single_use_recursive: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
inline_iife_within_arrow: {
|
||||
options = {
|
||||
arrows: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
var f = () => console.log(function(a) {
|
||||
return Math.ceil(a);
|
||||
}(Math.random()));
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var f = () => {
|
||||
return console.log((a = Math.random(), Math.ceil(a)));
|
||||
var a;
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect_stdout: "1"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4388: {
|
||||
options = {
|
||||
inline: true,
|
||||
@@ -1073,7 +1095,7 @@ issue_5414_2: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5416: {
|
||||
issue_5416_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
@@ -1095,10 +1117,11 @@ issue_5416: {
|
||||
expect: {
|
||||
var f = () => {
|
||||
{
|
||||
arguments = void 0;
|
||||
console;
|
||||
arguments = void 0,
|
||||
console.log(arguments);
|
||||
var arguments;
|
||||
return;
|
||||
}
|
||||
};
|
||||
f();
|
||||
@@ -1106,3 +1129,133 @@ issue_5416: {
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5416_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
loops: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = () => {
|
||||
while ((() => {
|
||||
console;
|
||||
var a = function g(arguments) {
|
||||
while (console.log(arguments));
|
||||
}();
|
||||
})());
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var f = () => {
|
||||
{
|
||||
console;
|
||||
var arguments = void 0;
|
||||
for (; console.log(arguments););
|
||||
return;
|
||||
}
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5416_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = () => {
|
||||
(() => {
|
||||
var a = function g(arguments) {
|
||||
console.log(arguments);
|
||||
}();
|
||||
})();
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var f = () => {
|
||||
arguments = void 0,
|
||||
console.log(arguments);
|
||||
var arguments;
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5416_4: {
|
||||
options = {
|
||||
arrows: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = () => {
|
||||
(() => {
|
||||
var a = function g(arguments) {
|
||||
while (console.log(arguments));
|
||||
}();
|
||||
})();
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var f = () => {
|
||||
var arguments = void 0;
|
||||
while (console.log(arguments));
|
||||
return;
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5495: {
|
||||
input: {
|
||||
console.log((() => {
|
||||
"use strict";
|
||||
return function() {
|
||||
return this;
|
||||
}();
|
||||
})());
|
||||
}
|
||||
expect_exact: 'console.log((()=>{"use strict";return function(){return this}()})());'
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5653: {
|
||||
options = {
|
||||
arrows: true,
|
||||
hoist_props: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log((a => {
|
||||
a = { p: console };
|
||||
return a++;
|
||||
})());
|
||||
}
|
||||
expect: {
|
||||
console.log((a => {
|
||||
return console, +{};
|
||||
})());
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -529,6 +529,7 @@ inline_block_await: {
|
||||
|
||||
inline_block_await_async: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
@@ -1046,6 +1047,60 @@ collapse_vars_3: {
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
collapse_funarg_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "FAIL";
|
||||
var a = "PASS";
|
||||
(async function({}, b) {
|
||||
return b;
|
||||
})(null, A = a);
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
A = "FAIL";
|
||||
var a = "PASS";
|
||||
(async function({}, b) {
|
||||
return b;
|
||||
})(null, A = a);
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
collapse_funarg_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
(async function() {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
})();
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
(async function() {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
})();
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
collapse_property_lambda: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -1293,6 +1348,21 @@ functions_inner_var: {
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
instanceof_lambda: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(42 instanceof async function() {});
|
||||
}
|
||||
expect: {
|
||||
console.log(false);
|
||||
}
|
||||
expect_stdout: "false"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_4335_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
@@ -2678,6 +2748,7 @@ issue_5177: {
|
||||
|
||||
issue_5250: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
@@ -2786,6 +2857,7 @@ issue_5298: {
|
||||
|
||||
issue_5305_1: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
@@ -2819,6 +2891,7 @@ issue_5305_1: {
|
||||
|
||||
issue_5305_2: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
@@ -2961,3 +3034,509 @@ issue_5478: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5493: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
(async function(a) {
|
||||
var b = await [ 42 || b, a = b ];
|
||||
console.log(a);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(async function(a) {
|
||||
var b = await [ 42 || b, a = b ];
|
||||
console.log(a);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5506: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
(async function() {
|
||||
a = null in (a = "PASS");
|
||||
})();
|
||||
return a;
|
||||
}("FAIL"));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
(async function() {
|
||||
a = null in (a = "PASS");
|
||||
})();
|
||||
return a;
|
||||
}("FAIL"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_1: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_2: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return 42;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return 42;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_3: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
FAIL;
|
||||
} catch (e) {
|
||||
return console.log("foo");
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
FAIL;
|
||||
} catch (e) {
|
||||
return console.log("foo");
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_4: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return {
|
||||
then() {
|
||||
console.log("foo");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return {
|
||||
then() {
|
||||
console.log("foo");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"bar",
|
||||
"baz",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5634_1: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
(async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
})();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
(async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
})();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5634_1_side_effects: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
(async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
})();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5634_2: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
await async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
await async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5634_2_side_effects: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
await async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5634_3: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5634_3_side_effects: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
@@ -241,6 +241,296 @@ class_super: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
static_newline_1: {
|
||||
input: {
|
||||
class A {
|
||||
static
|
||||
P
|
||||
}
|
||||
console.log("P" in A, "static" in A);
|
||||
console.log("P" in new A(), "static" in new A());
|
||||
}
|
||||
expect_exact: 'class A{static P}console.log("P"in A,"static"in A);console.log("P"in new A,"static"in new A);'
|
||||
expect_stdout: [
|
||||
"true false",
|
||||
"false false",
|
||||
]
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
static_newline_2: {
|
||||
input: {
|
||||
class A {
|
||||
static
|
||||
static
|
||||
P
|
||||
}
|
||||
console.log("P" in A, "static" in A);
|
||||
console.log("P" in new A(), "static" in new A());
|
||||
}
|
||||
expect_exact: 'class A{static static;P}console.log("P"in A,"static"in A);console.log("P"in new A,"static"in new A);'
|
||||
expect_stdout: [
|
||||
"false true",
|
||||
"true false",
|
||||
]
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
static_newline_3: {
|
||||
input: {
|
||||
class A {
|
||||
static
|
||||
static
|
||||
static
|
||||
P
|
||||
}
|
||||
console.log("P" in A, "static" in A);
|
||||
console.log("P" in new A(), "static" in new A());
|
||||
}
|
||||
expect_exact: 'class A{static static;static P}console.log("P"in A,"static"in A);console.log("P"in new A,"static"in new A);'
|
||||
expect_stdout: [
|
||||
"true true",
|
||||
"false false",
|
||||
]
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
static_newline_4: {
|
||||
input: {
|
||||
class A {
|
||||
static
|
||||
static
|
||||
static
|
||||
static
|
||||
P
|
||||
}
|
||||
console.log("P" in A, "static" in A);
|
||||
console.log("P" in new A(), "static" in new A());
|
||||
}
|
||||
expect_exact: 'class A{static static;static static;P}console.log("P"in A,"static"in A);console.log("P"in new A,"static"in new A);'
|
||||
expect_stdout: [
|
||||
"false true",
|
||||
"true false",
|
||||
]
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
static_newline_init: {
|
||||
input: {
|
||||
class A {
|
||||
static
|
||||
{
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_exact: 'class A{static{console.log("PASS")}}'
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
static_init: {
|
||||
input: {
|
||||
var a = "foo";
|
||||
var b = null;
|
||||
class A {
|
||||
static {
|
||||
var a = "bar";
|
||||
b = true;
|
||||
var c = 42;
|
||||
console.log(a, b, c);
|
||||
}
|
||||
}
|
||||
console.log(a, b, typeof c);
|
||||
}
|
||||
expect_exact: 'var a="foo";var b=null;class A{static{var a="bar";b=true;var c=42;console.log(a,b,c)}}console.log(a,b,typeof c);'
|
||||
expect_stdout: [
|
||||
"bar true 42",
|
||||
"foo true undefined",
|
||||
]
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
static_field_init: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(class {
|
||||
static [console.log("foo")] = console.log("bar");
|
||||
static {
|
||||
console.log("baz");
|
||||
}
|
||||
static [console.log("moo")] = console.log("moz");
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(class {
|
||||
static [(console.log("foo"), console.log("moo"))] = (
|
||||
console.log("bar"),
|
||||
(() => {
|
||||
console.log("baz");
|
||||
})(),
|
||||
console.log("moz")
|
||||
);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
"moz",
|
||||
]
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
static_field_init_strict: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(class {
|
||||
static [console.log("foo")] = console.log("bar");
|
||||
static {
|
||||
console.log("baz");
|
||||
}
|
||||
static [console.log("moo")] = console.log("moz");
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log("foo"),
|
||||
console.log("moo"),
|
||||
(() => (
|
||||
console.log("bar"),
|
||||
(() => {
|
||||
console.log("baz");
|
||||
})(),
|
||||
console.log("moz")
|
||||
))();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
"moz",
|
||||
]
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
static_init_side_effects_1: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
(class {
|
||||
static {
|
||||
a = "PASS";
|
||||
}
|
||||
});
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
(class {
|
||||
static {
|
||||
a = "PASS";
|
||||
}
|
||||
});
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
static_init_side_effects_1_strict: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "FAIL";
|
||||
(class {
|
||||
static {
|
||||
a = "PASS";
|
||||
}
|
||||
});
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "FAIL";
|
||||
(() => (() => {
|
||||
a = "PASS";
|
||||
})())();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
static_init_side_effects_2: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
(class {
|
||||
static {
|
||||
a = "PASS";
|
||||
}
|
||||
});
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
(class {
|
||||
static {
|
||||
a = "PASS";
|
||||
}
|
||||
});
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
static_init_side_effects_2_strict: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "FAIL";
|
||||
(class {
|
||||
static {
|
||||
a = "PASS";
|
||||
}
|
||||
});
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "FAIL";
|
||||
(() => (() => {
|
||||
a = "PASS";
|
||||
})())();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
block_scoped: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -456,6 +746,56 @@ separate_name: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
static_getter: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(class {
|
||||
static get p() {
|
||||
console.log("PASS");
|
||||
};
|
||||
}).p;
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(class {
|
||||
static get p() {
|
||||
console.log("PASS");
|
||||
};
|
||||
}).p;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
static_setter: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(class {
|
||||
static set p(v) {
|
||||
console.log(v);
|
||||
};
|
||||
}).p = "PASS";
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(class {
|
||||
static set p(v) {
|
||||
console.log(v);
|
||||
};
|
||||
}).p = "PASS";
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
static_side_effects: {
|
||||
options = {
|
||||
inline: true,
|
||||
@@ -1064,6 +1404,105 @@ keep_fnames: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
instanceof_lambda: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(42 instanceof class {});
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(false);
|
||||
}
|
||||
expect_stdout: "false"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
drop_instanceof: {
|
||||
options = {
|
||||
booleans: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A {}
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(!1, (Math, !1));
|
||||
}
|
||||
expect_stdout: "false false"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_instanceof_1: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A {}
|
||||
var A;
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
class A {}
|
||||
var A;
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect_stdout: SyntaxError("Identifier has already been declared")
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_instanceof_2: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var A = Object;
|
||||
class A {}
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var A = Object;
|
||||
class A {}
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect_stdout: SyntaxError("Identifier has already been declared")
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_instanceof_3: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A {}
|
||||
A = Object;
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
class A {}
|
||||
A = Object;
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect_stdout: "true true"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_805_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
@@ -1761,6 +2200,14 @@ mangle_properties: {
|
||||
console.log(A.s, new A().e);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
expect_warnings: [
|
||||
"INFO: Preserving reserved property q",
|
||||
"INFO: Preserving reserved property log",
|
||||
"INFO: Mapping property #P to #t",
|
||||
"INFO: Mapping property Q to s",
|
||||
"INFO: Mapping property #p to #i",
|
||||
"INFO: Mapping property r to e",
|
||||
]
|
||||
node_version: ">=14.6"
|
||||
}
|
||||
|
||||
@@ -2882,3 +3329,293 @@ issue_5481: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5489: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(class {
|
||||
[console.log("foo")];
|
||||
static {
|
||||
console.log("bar");
|
||||
}
|
||||
static [console.log("baz")]() {}
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(class {
|
||||
[(console.log("foo"), console.log("baz"))];
|
||||
static {
|
||||
console.log("bar");
|
||||
}
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
issue_5489_strict: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(class {
|
||||
[console.log("foo")];
|
||||
static {
|
||||
console.log("bar");
|
||||
}
|
||||
static [console.log("baz")]() {}
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log("foo"),
|
||||
console.log("baz"),
|
||||
(() => (() => {
|
||||
console.log("bar");
|
||||
})())();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
issue_5502: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "FAIL";
|
||||
class A {
|
||||
static p = a;
|
||||
[a = "PASS"];
|
||||
}
|
||||
try {
|
||||
b++;
|
||||
} finally {
|
||||
var a, b = 42;
|
||||
}
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "FAIL";
|
||||
class A {
|
||||
static p = a;
|
||||
[a = "PASS"];
|
||||
}
|
||||
try {
|
||||
b++;
|
||||
} finally {
|
||||
var a, b = 42;
|
||||
}
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5504: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a;
|
||||
console.log((a = 42, class {
|
||||
static p;
|
||||
}).p);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a;
|
||||
console.log((a = 42, class {
|
||||
static p;
|
||||
}).p);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5512: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
a = "PASS";
|
||||
class A {
|
||||
static {
|
||||
console.log(a);
|
||||
}
|
||||
static p = "PASS";
|
||||
}
|
||||
var a;
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
a = "PASS";
|
||||
class A {
|
||||
static {
|
||||
console.log(a);
|
||||
}
|
||||
static p = "PASS";
|
||||
}
|
||||
var a;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
issue_5531_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
class A {
|
||||
p = function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
}();
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect: {
|
||||
class A {
|
||||
p = function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
}();
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5531_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
class A {
|
||||
static p = function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
}();
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect: {
|
||||
class A {
|
||||
static p = (a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++), void 0);
|
||||
}
|
||||
var a;
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect_stdout: "foo"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5531_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
class A {
|
||||
static {
|
||||
(function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
})();
|
||||
}
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect: {
|
||||
class A {
|
||||
static {
|
||||
a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++),
|
||||
void 0;
|
||||
var a;
|
||||
}
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect_stdout: "foo"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
issue_5662: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(new (function() {
|
||||
var g = function(a) {
|
||||
return a;
|
||||
};
|
||||
return class {
|
||||
h(b) {
|
||||
return g(b);
|
||||
}
|
||||
};
|
||||
}())().h("PASS"));
|
||||
}
|
||||
expect: {
|
||||
console.log(new (function() {
|
||||
var g = function(a) {
|
||||
return a;
|
||||
};
|
||||
return class {
|
||||
h(b) {
|
||||
return g(b);
|
||||
}
|
||||
};
|
||||
}())().h("PASS"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -9321,12 +9321,11 @@ issue_4874: {
|
||||
})(a = 42);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
null;
|
||||
(function(b) {
|
||||
for (var c in a && a[console.log("PASS")])
|
||||
for (var c in 42, 42[console.log("PASS")])
|
||||
console;
|
||||
})(a = 42);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -9979,3 +9978,146 @@ issue_5396: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5568: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "FAIL";
|
||||
var a = (A = "PASS", !1);
|
||||
for (var b in a);
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
A = "FAIL";
|
||||
for (var b in !(A = "PASS"));
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5638_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console;
|
||||
a = [ 42 ];
|
||||
console || FAIL(a);
|
||||
console.log(a++);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console;
|
||||
a = [ 42 ];
|
||||
console || FAIL(a);
|
||||
console.log(a++);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5638_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console;
|
||||
a = [ 6 ];
|
||||
console || FAIL(a);
|
||||
console.log(a *= 7);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console;
|
||||
a = [ 6 ];
|
||||
console || FAIL(a);
|
||||
console.log(a *= 7);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5638_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var a = { foo: 42 }, b;
|
||||
for (var k in a) {
|
||||
b = a[k];
|
||||
log(k || b, b++);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var a = { foo: 42 }, b;
|
||||
for (var k in a) {
|
||||
b = a[k];
|
||||
log(k || b, b++);
|
||||
}
|
||||
}
|
||||
expect_stdout: "foo 42"
|
||||
}
|
||||
|
||||
issue_5638_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var a = { foo: 6 }, b;
|
||||
for (var k in a) {
|
||||
b = a[k];
|
||||
log(k || b, b *= 7);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var a = { foo: 6 }, b;
|
||||
for (var k in a) {
|
||||
b = a[k];
|
||||
log(k || b, b *= 7);
|
||||
}
|
||||
}
|
||||
expect_stdout: "foo 42"
|
||||
}
|
||||
|
||||
issue_5643: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 3, b;
|
||||
a *= 7;
|
||||
b = !!this;
|
||||
console || console.log(b);
|
||||
console.log(a * ++b);
|
||||
}
|
||||
expect: {
|
||||
var a = 3, b;
|
||||
a *= 7;
|
||||
b = !!this;
|
||||
console || console.log(b);
|
||||
console.log(a * ++b);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
@@ -40,6 +40,22 @@ unsafe_comps: {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe_in_instanceof: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unsafe_comps: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
42 in a;
|
||||
f() instanceof "foo";
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
f();
|
||||
}
|
||||
}
|
||||
|
||||
dont_change_in_or_instanceof_expressions: {
|
||||
input: {
|
||||
1 in 1;
|
||||
|
||||
@@ -196,6 +196,178 @@ ifs_7: {
|
||||
}
|
||||
}
|
||||
|
||||
merge_tail_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
} else {
|
||||
while (console.log("baz"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a)
|
||||
while (console.log("bar"));
|
||||
else
|
||||
while (console.log("baz"));
|
||||
console.log(b);
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"baz",
|
||||
"foo",
|
||||
"bar",
|
||||
"foo",
|
||||
]
|
||||
}
|
||||
|
||||
merge_tail_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
} else {
|
||||
c = "baz";
|
||||
while (console.log(c));
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
var c;
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (!a) {
|
||||
c = "baz";
|
||||
while (console.log(c));
|
||||
var c;
|
||||
}
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"baz",
|
||||
"bar",
|
||||
"foo",
|
||||
"bar",
|
||||
"foo",
|
||||
]
|
||||
}
|
||||
|
||||
merge_tail_sequence_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
} else {
|
||||
c = "baz";
|
||||
while (console.log(c));
|
||||
console.log("bar"),
|
||||
console.log(b);
|
||||
var c;
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a)
|
||||
while (console.log("bar"));
|
||||
else {
|
||||
c = "baz";
|
||||
while (console.log(c));
|
||||
console.log("bar");
|
||||
var c;
|
||||
}
|
||||
console.log(b);
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"baz",
|
||||
"bar",
|
||||
"foo",
|
||||
"bar",
|
||||
"foo",
|
||||
]
|
||||
}
|
||||
|
||||
merge_tail_sequence_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
console.log("bar");
|
||||
console.log(b);
|
||||
} else {
|
||||
c = "baz";
|
||||
while (console.log(c));
|
||||
console.log("bar"),
|
||||
console.log(b);
|
||||
var c;
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (!a) {
|
||||
c = "baz";
|
||||
while (console.log(c));
|
||||
var c;
|
||||
}
|
||||
console.log("bar");
|
||||
console.log(b);
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"baz",
|
||||
"bar",
|
||||
"foo",
|
||||
"bar",
|
||||
"foo",
|
||||
]
|
||||
}
|
||||
|
||||
cond_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
@@ -1004,6 +1176,52 @@ trivial_boolean_ternary_expressions : {
|
||||
}
|
||||
}
|
||||
|
||||
extendscript_1: {
|
||||
beautify = {
|
||||
extendscript: true,
|
||||
}
|
||||
input: {
|
||||
var alert = console.log;
|
||||
function f(a, b) {
|
||||
return a ? b ? "foo" : "bar" : "baz";
|
||||
}
|
||||
alert(f());
|
||||
alert(f(42));
|
||||
alert(f(null, true));
|
||||
alert(f([], {}));
|
||||
}
|
||||
expect_exact: 'var alert=console.log;function f(a,b){return a?(b?"foo":"bar"):"baz"}alert(f());alert(f(42));alert(f(null,true));alert(f([],{}));'
|
||||
expect_stdout: [
|
||||
"baz",
|
||||
"bar",
|
||||
"baz",
|
||||
"foo",
|
||||
]
|
||||
}
|
||||
|
||||
extendscript_2: {
|
||||
beautify = {
|
||||
extendscript: true,
|
||||
}
|
||||
input: {
|
||||
var alert = console.log;
|
||||
function f(a, b) {
|
||||
return a ? "foo" : b ? "bar" : "baz";
|
||||
}
|
||||
alert(f());
|
||||
alert(f(42));
|
||||
alert(f(null, true));
|
||||
alert(f([], {}));
|
||||
}
|
||||
expect_exact: 'var alert=console.log;function f(a,b){return a?"foo":(b?"bar":"baz")}alert(f());alert(f(42));alert(f(null,true));alert(f([],{}));'
|
||||
expect_stdout: [
|
||||
"baz",
|
||||
"foo",
|
||||
"bar",
|
||||
"foo",
|
||||
]
|
||||
}
|
||||
|
||||
issue_1154: {
|
||||
options = {
|
||||
booleans: true,
|
||||
@@ -1261,6 +1479,398 @@ condition_matches_alternative: {
|
||||
expect_stdout: "null 0 false 5"
|
||||
}
|
||||
|
||||
condition_sequence_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
return (console.log(x), x) ? x : y;
|
||||
}
|
||||
console.log(f("foo", "bar"));
|
||||
console.log(f(null, "baz"));
|
||||
console.log(f(42));
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
function f(x, y) {
|
||||
return console.log(x), x || y;
|
||||
}
|
||||
console.log(f("foo", "bar")),
|
||||
console.log(f(null, "baz")),
|
||||
console.log(f(42)),
|
||||
console.log(f());
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"foo",
|
||||
"null",
|
||||
"baz",
|
||||
"42",
|
||||
"42",
|
||||
"undefined",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
condition_sequence_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
return (console.log(y), y) ? x : y;
|
||||
}
|
||||
console.log(f("foo", "bar"));
|
||||
console.log(f(null, "baz"));
|
||||
console.log(f(42));
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
function f(x, y) {
|
||||
return console.log(y), y && x;
|
||||
}
|
||||
console.log(f("foo", "bar")),
|
||||
console.log(f(null, "baz")),
|
||||
console.log(f(42)),
|
||||
console.log(f());
|
||||
}
|
||||
expect_stdout: [
|
||||
"bar",
|
||||
"foo",
|
||||
"baz",
|
||||
"null",
|
||||
"undefined",
|
||||
"undefined",
|
||||
"undefined",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
combine_tail_sequence: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var n = {
|
||||
f: function() {
|
||||
console.log("foo");
|
||||
return this.p;
|
||||
},
|
||||
p: "FAIL 1",
|
||||
};
|
||||
var o = {
|
||||
f: function() {
|
||||
console.log("foz");
|
||||
return this.p;
|
||||
},
|
||||
p: "FAIL 2",
|
||||
};
|
||||
var p = "PASS";
|
||||
function g(a) {
|
||||
return a
|
||||
? (console.log("baa"), (console.log("bar"), (console.log("baz"), n).f)())
|
||||
: (console.log("moo"), (console.log("mor"), (console.log("moz"), o).f)());
|
||||
}
|
||||
console.log(g());
|
||||
console.log(g(42));
|
||||
}
|
||||
expect: {
|
||||
var n = {
|
||||
f: function() {
|
||||
console.log("foo");
|
||||
return this.p;
|
||||
},
|
||||
p: "FAIL 1",
|
||||
};
|
||||
var o = {
|
||||
f: function() {
|
||||
console.log("foz");
|
||||
return this.p;
|
||||
},
|
||||
p: "FAIL 2",
|
||||
};
|
||||
var p = "PASS";
|
||||
function g(a) {
|
||||
return (0, (a
|
||||
? (console.log("baa"), console.log("bar"), console.log("baz"), n)
|
||||
: (console.log("moo"), console.log("mor"), console.log("moz"), o)).f)();
|
||||
}
|
||||
console.log(g());
|
||||
console.log(g(42));
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"mor",
|
||||
"moz",
|
||||
"foz",
|
||||
"PASS",
|
||||
"baa",
|
||||
"bar",
|
||||
"baz",
|
||||
"foo",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
consequent_sequence_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y, a) {
|
||||
return x ? (console.log("seq"), y && a) : a;
|
||||
}
|
||||
console.log(f(false, false, 1));
|
||||
console.log(f(false, true, 2));
|
||||
console.log(f(true, false, 3));
|
||||
console.log(f(true, true, 4));
|
||||
}
|
||||
expect: {
|
||||
function f(x, y, a) {
|
||||
return (!x || (console.log("seq"), y)) && a;
|
||||
}
|
||||
console.log(f(false, false, 1));
|
||||
console.log(f(false, true, 2));
|
||||
console.log(f(true, false, 3));
|
||||
console.log(f(true, true, 4));
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
"seq",
|
||||
"false",
|
||||
"seq",
|
||||
"4",
|
||||
]
|
||||
}
|
||||
|
||||
consequent_sequence_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y, a) {
|
||||
return x ? (console.log("seq"), y || a) : a;
|
||||
}
|
||||
console.log(f(false, false, 1));
|
||||
console.log(f(false, true, 2));
|
||||
console.log(f(true, false, 3));
|
||||
console.log(f(true, true, 4));
|
||||
}
|
||||
expect: {
|
||||
function f(x, y, a) {
|
||||
return x && (console.log("seq"), y) || a;
|
||||
}
|
||||
console.log(f(false, false, 1));
|
||||
console.log(f(false, true, 2));
|
||||
console.log(f(true, false, 3));
|
||||
console.log(f(true, true, 4));
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
"seq",
|
||||
"3",
|
||||
"seq",
|
||||
"true",
|
||||
]
|
||||
}
|
||||
|
||||
consequent_sequence_3: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y, a, b) {
|
||||
return x ? (console.log("seq"), y ? a : b) : b;
|
||||
}
|
||||
console.log(f(false, false, 1, -1));
|
||||
console.log(f(false, true, 2, -2));
|
||||
console.log(f(true, false, 3, -3));
|
||||
console.log(f(true, true, 4, -4));
|
||||
}
|
||||
expect: {
|
||||
function f(x, y, a, b) {
|
||||
return x && (console.log("seq"), y) ? a : b;
|
||||
}
|
||||
console.log(f(false, false, 1, -1));
|
||||
console.log(f(false, true, 2, -2));
|
||||
console.log(f(true, false, 3, -3));
|
||||
console.log(f(true, true, 4, -4));
|
||||
}
|
||||
expect_stdout: [
|
||||
"-1",
|
||||
"-2",
|
||||
"seq",
|
||||
"-3",
|
||||
"seq",
|
||||
"4",
|
||||
]
|
||||
}
|
||||
|
||||
consequent_sequence_4: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y, a, b) {
|
||||
return x ? (console.log("seq"), y ? a : b) : a;
|
||||
}
|
||||
console.log(f(false, false, 1, -1));
|
||||
console.log(f(false, true, 2, -2));
|
||||
console.log(f(true, false, 3, -3));
|
||||
console.log(f(true, true, 4, -4));
|
||||
}
|
||||
expect: {
|
||||
function f(x, y, a, b) {
|
||||
return !x || (console.log("seq"), y) ? a : b;
|
||||
}
|
||||
console.log(f(false, false, 1, -1));
|
||||
console.log(f(false, true, 2, -2));
|
||||
console.log(f(true, false, 3, -3));
|
||||
console.log(f(true, true, 4, -4));
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
"seq",
|
||||
"-3",
|
||||
"seq",
|
||||
"4",
|
||||
]
|
||||
}
|
||||
|
||||
alternative_sequence_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y, a) {
|
||||
return x ? a : (console.log("seq"), y && a);
|
||||
}
|
||||
console.log(f(false, false, 1));
|
||||
console.log(f(false, true, 2));
|
||||
console.log(f(true, false, 3));
|
||||
console.log(f(true, true, 4));
|
||||
}
|
||||
expect: {
|
||||
function f(x, y, a) {
|
||||
return (x || (console.log("seq"), y)) && a;
|
||||
}
|
||||
console.log(f(false, false, 1));
|
||||
console.log(f(false, true, 2));
|
||||
console.log(f(true, false, 3));
|
||||
console.log(f(true, true, 4));
|
||||
}
|
||||
expect_stdout: [
|
||||
"seq",
|
||||
"false",
|
||||
"seq",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
]
|
||||
}
|
||||
|
||||
alternative_sequence_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y, a) {
|
||||
return x ? a : (console.log("seq"), y || a);
|
||||
}
|
||||
console.log(f(false, false, 1));
|
||||
console.log(f(false, true, 2));
|
||||
console.log(f(true, false, 3));
|
||||
console.log(f(true, true, 4));
|
||||
}
|
||||
expect: {
|
||||
function f(x, y, a) {
|
||||
return !x && (console.log("seq"), y) || a;
|
||||
}
|
||||
console.log(f(false, false, 1));
|
||||
console.log(f(false, true, 2));
|
||||
console.log(f(true, false, 3));
|
||||
console.log(f(true, true, 4));
|
||||
}
|
||||
expect_stdout: [
|
||||
"seq",
|
||||
"1",
|
||||
"seq",
|
||||
"true",
|
||||
"3",
|
||||
"4",
|
||||
]
|
||||
}
|
||||
|
||||
alternative_sequence_3: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y, a, b) {
|
||||
return x ? a : (console.log("seq"), y ? a : b);
|
||||
}
|
||||
console.log(f(false, false, 1, -1));
|
||||
console.log(f(false, true, 2, -2));
|
||||
console.log(f(true, false, 3, -3));
|
||||
console.log(f(true, true, 4, -4));
|
||||
}
|
||||
expect: {
|
||||
function f(x, y, a, b) {
|
||||
return x || (console.log("seq"), y) ? a : b;
|
||||
}
|
||||
console.log(f(false, false, 1, -1));
|
||||
console.log(f(false, true, 2, -2));
|
||||
console.log(f(true, false, 3, -3));
|
||||
console.log(f(true, true, 4, -4));
|
||||
}
|
||||
expect_stdout: [
|
||||
"seq",
|
||||
"-1",
|
||||
"seq",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
]
|
||||
}
|
||||
|
||||
alternative_sequence_4: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y, a, b) {
|
||||
return x ? b : (console.log("seq"), y ? a : b);
|
||||
}
|
||||
console.log(f(false, false, 1, -1));
|
||||
console.log(f(false, true, 2, -2));
|
||||
console.log(f(true, false, 3, -3));
|
||||
console.log(f(true, true, 4, -4));
|
||||
}
|
||||
expect: {
|
||||
function f(x, y, a, b) {
|
||||
return !x && (console.log("seq"), y) ? a : b;
|
||||
}
|
||||
console.log(f(false, false, 1, -1));
|
||||
console.log(f(false, true, 2, -2));
|
||||
console.log(f(true, false, 3, -3));
|
||||
console.log(f(true, true, 4, -4));
|
||||
}
|
||||
expect_stdout: [
|
||||
"seq",
|
||||
"-1",
|
||||
"seq",
|
||||
"2",
|
||||
"-3",
|
||||
"-4",
|
||||
]
|
||||
}
|
||||
|
||||
delete_conditional_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
@@ -1731,7 +2341,7 @@ issue_3576: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3668: {
|
||||
issue_3668_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
@@ -1748,6 +2358,38 @@ issue_3668: {
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
try {
|
||||
var undefined = typeof f;
|
||||
if (!f) return undefined;
|
||||
} catch (e) {
|
||||
return "FAIL";
|
||||
}
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_3668_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
var undefined = typeof f;
|
||||
if (!f) return undefined;
|
||||
return;
|
||||
} catch (e) {
|
||||
return "FAIL";
|
||||
}
|
||||
FAIL;
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
try {
|
||||
@@ -1756,6 +2398,7 @@ issue_3668: {
|
||||
} catch (e) {
|
||||
return "FAIL";
|
||||
}
|
||||
FAIL;
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
@@ -2062,3 +2705,226 @@ issue_5334_2: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5544_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
if (a)
|
||||
switch (42) {
|
||||
case console.log("FAIL"):
|
||||
case console:
|
||||
}
|
||||
else
|
||||
switch (false) {
|
||||
case console.log("PASS"):
|
||||
case console:
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
if (a)
|
||||
switch (42) {
|
||||
case console.log("FAIL"):
|
||||
case console:
|
||||
}
|
||||
else
|
||||
switch (false) {
|
||||
case console.log("PASS"):
|
||||
case console:
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5544_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
if (a)
|
||||
switch (42) {
|
||||
case console.log("FAIL"):
|
||||
case console:
|
||||
}
|
||||
else
|
||||
switch (42) {
|
||||
case console.log("PASS"):
|
||||
case console:
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
if (a)
|
||||
switch (42) {
|
||||
case console.log("FAIL"):
|
||||
case console:
|
||||
}
|
||||
else
|
||||
switch (42) {
|
||||
case console.log("PASS"):
|
||||
case console:
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5546_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
if (a)
|
||||
try {
|
||||
console;
|
||||
} finally {
|
||||
console.log("FAIL");
|
||||
}
|
||||
else
|
||||
try {
|
||||
console;
|
||||
} finally {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
if (a)
|
||||
try {
|
||||
console;
|
||||
} finally {
|
||||
console.log("FAIL");
|
||||
}
|
||||
else
|
||||
try {
|
||||
console;
|
||||
} finally {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5546_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
if (a)
|
||||
try {
|
||||
console;
|
||||
} catch (e) {}
|
||||
else
|
||||
try {
|
||||
console;
|
||||
} finally {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
if (a)
|
||||
try {
|
||||
console;
|
||||
} catch (e) {}
|
||||
else
|
||||
try {
|
||||
console;
|
||||
} finally {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5546_3: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
if (a)
|
||||
try {
|
||||
FAIL;
|
||||
} catch (e) {
|
||||
console.log("FAIL");
|
||||
}
|
||||
else
|
||||
try {
|
||||
FAIL;
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
if (a)
|
||||
try {
|
||||
FAIL;
|
||||
} catch (e) {
|
||||
console.log("FAIL");
|
||||
}
|
||||
else
|
||||
try {
|
||||
FAIL;
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5666_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
(function() {
|
||||
var b = a;
|
||||
a ? a = b : (b++, a = b);
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
(function() {
|
||||
var b = a;
|
||||
a = (a ? 0 : b++, b);
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
issue_5666_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
(function() {
|
||||
var b = a;
|
||||
a ? (b++, a = b) : a = b;
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
(function() {
|
||||
var b = a;
|
||||
a = (a ? b++ : 0, b);
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
@@ -142,6 +142,80 @@ if_dead_branch: {
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
retain_tail_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
const b = "bar";
|
||||
while (console.log("baz"));
|
||||
console.log(b);
|
||||
} else {
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
const b = "bar";
|
||||
while (console.log("baz"));
|
||||
console.log(b);
|
||||
} else {
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
retain_tail_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
} else {
|
||||
const b = "baz";
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
} else {
|
||||
const b = "baz";
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
merge_vars_1: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
@@ -579,6 +653,37 @@ dead_block_after_return: {
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
if_return_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
const b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
const b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
do_if_continue_1: {
|
||||
options = {
|
||||
if_return: true,
|
||||
@@ -1872,3 +1977,230 @@ issue_5476: {
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_5516: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function() {
|
||||
try {} catch (a) {
|
||||
(function f() {
|
||||
a;
|
||||
})();
|
||||
}
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function() {
|
||||
try {} catch (a) {
|
||||
void a;
|
||||
}
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_5580_1: {
|
||||
mangle = {}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(function(a, b, c) {
|
||||
try {
|
||||
FAIL;
|
||||
} catch (e) {
|
||||
return function() {
|
||||
var d = e, i, j;
|
||||
{
|
||||
const e = j;
|
||||
}
|
||||
return a;
|
||||
}();
|
||||
} finally {
|
||||
const e = 42;
|
||||
}
|
||||
}("PASS"));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function(r, n, t) {
|
||||
try {
|
||||
FAIL;
|
||||
} catch (o) {
|
||||
return function() {
|
||||
var n = o, t, c;
|
||||
{
|
||||
const o = c;
|
||||
}
|
||||
return r;
|
||||
}();
|
||||
} finally {
|
||||
const c = 42;
|
||||
}
|
||||
}("PASS"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5580_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function() {
|
||||
try {
|
||||
throw "PASS";
|
||||
} catch (e) {
|
||||
return function() {
|
||||
console.log(e);
|
||||
{
|
||||
const e = "FAIL 1";
|
||||
}
|
||||
}();
|
||||
} finally {
|
||||
const e = "FAIL 2";
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function() {
|
||||
try {
|
||||
throw "PASS";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
{
|
||||
const e = "FAIL 1";
|
||||
}
|
||||
return;
|
||||
} finally {
|
||||
var e = "FAIL 2";
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5591: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
switch (console.log("foo")) {
|
||||
case console.log("bar"):
|
||||
if (console.log("baz"))
|
||||
return;
|
||||
else {
|
||||
const a = 42;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
switch (console.log("foo")) {
|
||||
case console.log("bar"):
|
||||
if (console.log("baz"))
|
||||
return;
|
||||
else {
|
||||
const a = 42;
|
||||
return;
|
||||
}
|
||||
case null:
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5656: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
merge_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
var b = a;
|
||||
b++;
|
||||
{
|
||||
const a = b;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
var b = a;
|
||||
{
|
||||
const a = ++b;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_5660: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
a;
|
||||
var b;
|
||||
return b;
|
||||
} catch (e) {
|
||||
var a = "FAIL";
|
||||
const b = null;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
try {
|
||||
var b;
|
||||
return b;
|
||||
} catch (e) {
|
||||
var a = "FAIL";
|
||||
const b = null;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -1485,8 +1485,6 @@ self_assignments_5: {
|
||||
}
|
||||
expect: {
|
||||
var i = 0, l = [ "FAIL", "PASS" ];
|
||||
l[0];
|
||||
l[0];
|
||||
l[0] = l[1];
|
||||
console.log(l[0], 2);
|
||||
}
|
||||
@@ -1669,3 +1667,66 @@ issue_5106_2: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5506: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
(function(a) {
|
||||
var b = 1;
|
||||
(function f() {
|
||||
try {
|
||||
b-- && f();
|
||||
} catch (c) {}
|
||||
console.log(a);
|
||||
a = 42 in (a = "bar");
|
||||
})();
|
||||
})("foo");
|
||||
} catch (e) {}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
(function(a) {
|
||||
var b = 1;
|
||||
(function f() {
|
||||
try {
|
||||
b-- && f();
|
||||
} catch (c) {}
|
||||
console.log(a);
|
||||
a = 42 in (a = "bar");
|
||||
})();
|
||||
})("foo");
|
||||
} catch (e) {}
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5641: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
if (a || b) {
|
||||
var b = "PASS", c = b && console.log(b);
|
||||
} else
|
||||
var d = a || b;
|
||||
}
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var b, c, d;
|
||||
(a || b) && (b = "PASS") && console.log(b);
|
||||
}
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -180,6 +180,26 @@ collapse_arg_sequence: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
collapse_in_arg: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, b = a) {
|
||||
b("PASS");
|
||||
})(console.log);
|
||||
}
|
||||
expect: {
|
||||
(function(a) {
|
||||
a("PASS");
|
||||
})(console.log);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
collapse_value_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -541,7 +561,7 @@ inline_side_effects_2: {
|
||||
}
|
||||
expect: {
|
||||
var a = 42;
|
||||
[ [].e = --a ] = [ console ];
|
||||
[ [][0] = --a ] = [ console ];
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
@@ -648,6 +668,8 @@ drop_fargs: {
|
||||
hoist_vars: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
@@ -655,8 +677,7 @@ hoist_vars: {
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
var [ b = 42 ] = [];
|
||||
var a = "PASS", [ b = 42 ] = [];
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
@@ -1170,6 +1191,49 @@ mangle_arrow_2_toplevel: {
|
||||
node_version: ">=6.9.3"
|
||||
}
|
||||
|
||||
collapse_preceding_simple_arg: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
console.log(function(b, c = "bar") {
|
||||
return b + c;
|
||||
}(a, a));
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
console.log(function(b, c = "bar") {
|
||||
return a + c;
|
||||
}(0, a));
|
||||
}
|
||||
expect_stdout: "foofoo"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
drop_preceding_simple_arg: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
console.log(function(b, c = "bar") {
|
||||
return b + c;
|
||||
}(a, a));
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
console.log(function(c = "bar") {
|
||||
return a + c;
|
||||
}(a));
|
||||
}
|
||||
expect_stdout: "foofoo"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4444: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -1558,7 +1622,7 @@ issue_4502_4: {
|
||||
(function(a, b = console.log("FAIL")) {})(..."" + console.log(42));
|
||||
}
|
||||
expect: {
|
||||
[ , [].e = console.log("FAIL") ] = [ ..."" + console.log(42) ];
|
||||
[ , [][0] = console.log("FAIL") ] = [ ..."" + console.log(42) ];
|
||||
}
|
||||
expect_stdout: "42"
|
||||
node_version: ">=6"
|
||||
@@ -1655,7 +1719,7 @@ issue_4540: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4548: {
|
||||
issue_4548_1: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
@@ -1681,6 +1745,32 @@ issue_4548: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4548_2: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
A = "foo";
|
||||
var a = A;
|
||||
var [ b = c = "bar" ] = [ console, console.log(a) ];
|
||||
console.log(c);
|
||||
var c;
|
||||
}
|
||||
expect: {
|
||||
A = "foo";
|
||||
var a = A;
|
||||
var [ b = c = "bar" ] = [ console, console.log(a) ];
|
||||
console.log(c);
|
||||
var c;
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4588_1_unused: {
|
||||
options = {
|
||||
unused: true,
|
||||
@@ -2023,7 +2113,7 @@ issue_5246_1: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
expect_warnings: [
|
||||
"INFO: Dropping unused default argument {}=42 [test/compress/default-values.js:1,29]",
|
||||
"INFO: Dropping unused default argument {} [test/compress/default-values.js:1,29]",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
@@ -2183,7 +2273,7 @@ issue_5340_2: {
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
[ [].e = 0 ] = [ ({ p: a } = true).q ];
|
||||
[ [][0] = 0 ] = [ ({ p: a } = true).q ];
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
@@ -2415,7 +2505,7 @@ issue_5463: {
|
||||
var a, b, b;
|
||||
console.log("PASS") && (
|
||||
b = a = void 0,
|
||||
b = [a = FAIL] = a && a
|
||||
b = [a = FAIL] = a
|
||||
);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -2462,3 +2552,520 @@ issue_5485: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_1_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_1_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ] = []) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ] = []) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [ , ] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_3_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, c = null) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_3_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, c = null) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_4_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, [ c ] = []) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_4_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, [ c ] = []) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5536: {
|
||||
options = {
|
||||
inline: true,
|
||||
keep_fargs: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function*() {
|
||||
(([], a = 42) => {})([]);
|
||||
console.log(typeof a);
|
||||
})().next();
|
||||
}
|
||||
expect: {
|
||||
(function*() {
|
||||
[ , [][0] = 0 ] = [ [] ],
|
||||
void 0;
|
||||
console.log(typeof a);
|
||||
})().next();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5566_1: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
var a = "foo";
|
||||
console.log(a, f());
|
||||
})("bar");
|
||||
}
|
||||
expect: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
var a = "foo";
|
||||
console.log(a, f());
|
||||
})("bar");
|
||||
}
|
||||
expect_stdout: "foo bar"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5566_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
function a() {}
|
||||
console.log(typeof a, typeof f());
|
||||
})(42);
|
||||
}
|
||||
expect: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
function a() {}
|
||||
console.log(typeof a, typeof f());
|
||||
})(42);
|
||||
}
|
||||
expect_stdout: "function number"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5566_3: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
function a() {}
|
||||
console.log(typeof a, typeof f());
|
||||
})(42);
|
||||
}
|
||||
expect: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
function a() {}
|
||||
console.log(typeof a, typeof f());
|
||||
})(42);
|
||||
}
|
||||
expect_stdout: "function number"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5566_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, b = function() {
|
||||
return a;
|
||||
}) {
|
||||
var a = 0;
|
||||
b()("PASS");
|
||||
})(console.log);
|
||||
}
|
||||
expect: {
|
||||
(function(a, b = function() {
|
||||
return a;
|
||||
}) {
|
||||
var a = 0;
|
||||
b()("PASS");
|
||||
})(console.log);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5566_5: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
var a = "foo";
|
||||
var b;
|
||||
console.log(a, f());
|
||||
})("bar");
|
||||
}
|
||||
expect: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
var a, b;
|
||||
a = "foo";
|
||||
console.log(a, f());
|
||||
})("bar");
|
||||
}
|
||||
expect_stdout: "foo bar"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5651: {
|
||||
options = {
|
||||
ie: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function arguments(a = "FAIL") {
|
||||
try {} catch (arguments) {
|
||||
var arguments;
|
||||
}
|
||||
return arguments[0];
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function arguments(a = "FAIL") {
|
||||
try {} catch (arguments) {
|
||||
var arguments;
|
||||
}
|
||||
return arguments[0];
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -472,6 +472,93 @@ funarg_collapse_vars_3: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
funarg_collapse_vars_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
(function(b, { log: c }) {
|
||||
c(b);
|
||||
})(a, console);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
(function(b, { log: c }) {
|
||||
c(a);
|
||||
})(0, console);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
funarg_collapse_vars_5: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
try {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
} catch (e) {}
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
try {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
} catch (e) {}
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
funarg_collapse_vars_6: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
function f() {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
}
|
||||
try {
|
||||
f();
|
||||
} catch (e) {
|
||||
console.log(A);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
function f() {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
}
|
||||
try {
|
||||
f();
|
||||
} catch (e) {
|
||||
console.log(A);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
funarg_reduce_vars_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
@@ -1219,7 +1306,7 @@ keep_reference: {
|
||||
}
|
||||
expect: {
|
||||
var a = [ {}, 42 ];
|
||||
var [ b ] = a;
|
||||
var b = a[0];
|
||||
console.log(a[0] === b ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -1565,6 +1652,8 @@ fn_name_unused: {
|
||||
hoist_vars: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
@@ -1572,8 +1661,7 @@ hoist_vars: {
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
var [ b ] = [ 42 ];
|
||||
var a = "PASS", b = [ 42 ][0];
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
@@ -1815,8 +1903,8 @@ issue_4288: {
|
||||
console.log(typeof b);
|
||||
}()]: a,
|
||||
}) {
|
||||
var b = a;
|
||||
b++;
|
||||
var a = a;
|
||||
a++;
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
@@ -1989,17 +2077,16 @@ issue_4312: {
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
b = "PASS",
|
||||
c = "FAIL",
|
||||
[
|
||||
{
|
||||
[a = b]: d,
|
||||
[c = b]: d,
|
||||
},
|
||||
] = [ c && c ],
|
||||
void 0;
|
||||
var b, c, d;
|
||||
console.log(a);
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
@@ -3497,7 +3584,7 @@ issue_5314_2: {
|
||||
A = this;
|
||||
new function() {
|
||||
[ {
|
||||
[console.log(this === A ? "FAIL" : "PASS")]: [].e,
|
||||
[console.log(this === A ? "FAIL" : "PASS")]: [][0],
|
||||
} ] = [ 42 ];
|
||||
}();
|
||||
}
|
||||
@@ -3646,3 +3733,139 @@ issue_5485: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})([]);
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})([]);
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5573: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var a = "FAIL";
|
||||
(function([ { [log(a)]: b } ]) {
|
||||
A = 42;
|
||||
})((a = "PASS", [ {} ]));
|
||||
log(a, A);
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var a = "FAIL";
|
||||
(function([ { [log(a)]: b } ]) {
|
||||
A = 42;
|
||||
})((a = "PASS", [ {} ]));
|
||||
log(a, A);
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS 42",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5651: {
|
||||
options = {
|
||||
ie: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function arguments({}) {
|
||||
try {} catch (arguments) {
|
||||
var arguments;
|
||||
}
|
||||
return arguments[0];
|
||||
}("PASS"));
|
||||
}
|
||||
expect: {
|
||||
console.log(function arguments({}) {
|
||||
try {} catch (arguments) {
|
||||
var arguments;
|
||||
}
|
||||
return arguments[0];
|
||||
}("PASS"));
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -131,19 +131,34 @@ valid_after_invalid_2: {
|
||||
}
|
||||
|
||||
issue_5368_1: {
|
||||
expression = true
|
||||
options = {
|
||||
directives: true,
|
||||
expression: true,
|
||||
}
|
||||
input: {
|
||||
"foo";
|
||||
}
|
||||
expect: {
|
||||
"foo";
|
||||
"foo"
|
||||
}
|
||||
expect_exact: '"foo"'
|
||||
expect_stdout: "foo"
|
||||
}
|
||||
|
||||
issue_5368_2: {
|
||||
expression = true
|
||||
options = {
|
||||
directives: true,
|
||||
expression: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
"foo";
|
||||
})()
|
||||
}
|
||||
expect_exact: "function(){}()"
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_5368_3: {
|
||||
options = {
|
||||
directives: true,
|
||||
expression: true,
|
||||
|
||||
@@ -409,6 +409,15 @@ drop_toplevel_retain: {
|
||||
a = 2;
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
|
||||
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
|
||||
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
|
||||
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_retain_array: {
|
||||
@@ -442,6 +451,15 @@ drop_toplevel_retain_array: {
|
||||
a = 2;
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
|
||||
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
|
||||
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
|
||||
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_retain_regex: {
|
||||
@@ -471,6 +489,15 @@ drop_toplevel_retain_regex: {
|
||||
a = 2;
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
|
||||
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
|
||||
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
|
||||
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_all_retain: {
|
||||
@@ -501,6 +528,15 @@ drop_toplevel_all_retain: {
|
||||
a = 2;
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
|
||||
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
|
||||
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
|
||||
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_funcs_retain: {
|
||||
@@ -532,6 +568,12 @@ drop_toplevel_funcs_retain: {
|
||||
function g() {}
|
||||
console.log(b = 3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_vars_retain: {
|
||||
@@ -564,6 +606,13 @@ drop_toplevel_vars_retain: {
|
||||
function h() {}
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
|
||||
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_keep_assign: {
|
||||
@@ -671,6 +720,76 @@ iife: {
|
||||
}
|
||||
}
|
||||
|
||||
drop_instanceof: {
|
||||
options = {
|
||||
booleans: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
console.log(!1, (Math, !1));
|
||||
}
|
||||
expect_stdout: "false false"
|
||||
}
|
||||
|
||||
keep_instanceof_1: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
var f;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
var f;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect_stdout: "false false"
|
||||
}
|
||||
|
||||
keep_instanceof_2: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
var f = Object;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
var f = Object;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect_stdout: "true true"
|
||||
}
|
||||
|
||||
keep_instanceof_3: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
f = Object;
|
||||
function f() {}
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
f = Object;
|
||||
function f() {}
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect_stdout: "true true"
|
||||
}
|
||||
|
||||
issue_1539: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -1759,7 +1878,7 @@ issue_2846: {
|
||||
var c = function(a, b) {
|
||||
a = 0;
|
||||
b && b(a);
|
||||
return a++;
|
||||
return +a;
|
||||
}();
|
||||
console.log(c);
|
||||
}
|
||||
@@ -2857,14 +2976,12 @@ issue_4025: {
|
||||
console.log(a, b, d);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
try {
|
||||
console.log(c);
|
||||
console.log(0);
|
||||
} finally {
|
||||
var d = c + 1;
|
||||
c = 0;
|
||||
0;
|
||||
}
|
||||
console.log(1, 1, d);
|
||||
console.log(1, 1, 1);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0",
|
||||
@@ -3577,7 +3694,7 @@ issue_5224: {
|
||||
(function() {
|
||||
var a = "FAIL 1";
|
||||
null;
|
||||
a = console.log(a);
|
||||
console.log(a);
|
||||
})(function() {
|
||||
console.log(1 / 0);
|
||||
a;
|
||||
@@ -3615,3 +3732,85 @@ issue_5271: {
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5533_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5533_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -907,6 +907,20 @@ chained_side_effects: {
|
||||
]
|
||||
}
|
||||
|
||||
instanceof_lambda: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(42 instanceof function() {});
|
||||
}
|
||||
expect: {
|
||||
console.log(false);
|
||||
}
|
||||
expect_stdout: "false"
|
||||
}
|
||||
|
||||
issue_1649: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -3376,3 +3390,29 @@ issue_5380: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5558: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 99, b = 0;
|
||||
a++;
|
||||
b++;
|
||||
b += a;
|
||||
b *= a;
|
||||
b += a;
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 99, b = 0;
|
||||
b++,
|
||||
b = (b += ++a) * a + a,
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "100"
|
||||
}
|
||||
|
||||
@@ -109,6 +109,17 @@ foreign: {
|
||||
expect_exact: 'export*from"foo";export{}from"bar";export*as a from"baz";export{default}from"moo";export{b,c as case,default as delete,d}from"moz";'
|
||||
}
|
||||
|
||||
non_identifiers: {
|
||||
beautify = {
|
||||
quote_style: 3,
|
||||
}
|
||||
input: {
|
||||
export * as "42" from 'foo';
|
||||
export { '42', "delete" as 'foo' } from "bar";
|
||||
}
|
||||
expect_exact: "export*as\"42\"from'foo';export{'42',delete as foo}from\"bar\";"
|
||||
}
|
||||
|
||||
same_quotes: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
@@ -417,6 +428,46 @@ hoist_funs: {
|
||||
expect_exact: "export function f(){}export default async function*g(){}"
|
||||
}
|
||||
|
||||
instanceof_default_class: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
export default class A {
|
||||
f(a) {
|
||||
return a instanceof A;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
export default class A {
|
||||
f(a) {
|
||||
return a instanceof A;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
instanceof_default_function: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
export default function f() {
|
||||
if (!(this instanceof f))
|
||||
throw new Error("must instantiate");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
export default function f() {
|
||||
if (!(this instanceof f))
|
||||
throw new Error("must instantiate");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_4742_join_vars_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
@@ -509,3 +560,23 @@ issue_5444: {
|
||||
export var a = console;
|
||||
}
|
||||
}
|
||||
|
||||
issue_5628: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
export default function f() {
|
||||
for (a in 42);
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
export default function f() {
|
||||
for (a in 42);
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,7 +629,7 @@ inline_binary_and: {
|
||||
return void "moo";
|
||||
return;
|
||||
} else
|
||||
return;
|
||||
return void 0;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
@@ -5512,6 +5512,40 @@ substitute_use_strict: {
|
||||
]
|
||||
}
|
||||
|
||||
substitute_assignment: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b, c) {
|
||||
a[b] = c;
|
||||
}
|
||||
var o = {};
|
||||
f(o, 42, null);
|
||||
f(o, "foo", "bar");
|
||||
for (var k in o)
|
||||
console.log(k, o[k]);
|
||||
}
|
||||
expect: {
|
||||
var o = {};
|
||||
o[42] = null;
|
||||
o.foo = "bar";
|
||||
for (var k in o)
|
||||
console.log(k, o[k]);
|
||||
}
|
||||
expect_stdout: [
|
||||
"42 null",
|
||||
"foo bar",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3833_1: {
|
||||
options = {
|
||||
inline: 3,
|
||||
@@ -5582,7 +5616,7 @@ issue_3835: {
|
||||
return f();
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_stdout: RangeError("Maximum call stack size exceeded")
|
||||
}
|
||||
|
||||
issue_3836_1: {
|
||||
@@ -7835,7 +7869,7 @@ issue_5249_1: {
|
||||
while (console.log("FAIL 2"));
|
||||
return;
|
||||
} else
|
||||
return;
|
||||
return void 0;
|
||||
throw "FAIL 3";
|
||||
}());
|
||||
}
|
||||
@@ -8646,3 +8680,42 @@ module_inline: {
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
single_use_inline_collision: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
(function() {
|
||||
var f = function() {
|
||||
while (console.log(a));
|
||||
};
|
||||
(function() {
|
||||
(function() {
|
||||
f();
|
||||
})();
|
||||
(function(a) {
|
||||
a || a("FAIL");
|
||||
})(console.log);
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
(function() {
|
||||
(function() {
|
||||
while (console.log(a));
|
||||
return;
|
||||
})();
|
||||
(function(a) {
|
||||
a || a("FAIL");
|
||||
})(console.log);
|
||||
return;
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -462,6 +462,11 @@ issue_2473_1: {
|
||||
var x = {};
|
||||
var y = [];
|
||||
}
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable x",
|
||||
"INFO: Retaining variable y",
|
||||
"WARN: Dropping unused variable z [test/compress/hoist_props.js:3,12]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2473_2: {
|
||||
@@ -484,6 +489,11 @@ issue_2473_2: {
|
||||
var x = {};
|
||||
var y = [];
|
||||
}
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable x",
|
||||
"INFO: Retaining variable y",
|
||||
"WARN: Dropping unused variable z [test/compress/hoist_props.js:3,12]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2473_3: {
|
||||
@@ -509,6 +519,9 @@ issue_2473_3: {
|
||||
console.log(o.a, o.b);
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable o",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2473_4: {
|
||||
@@ -535,6 +548,9 @@ issue_2473_4: {
|
||||
})();
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
expect_warnings: [
|
||||
"INFO: Dropping unused variable o [test/compress/hoist_props.js:2,16]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2508_1: {
|
||||
@@ -1203,3 +1219,24 @@ issue_5441: {
|
||||
}
|
||||
expect_stdout: "object"
|
||||
}
|
||||
|
||||
issue_5498: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
__proto__: 42,
|
||||
};
|
||||
while (console.log(typeof o.__proto__));
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
__proto__: 42,
|
||||
};
|
||||
while (console.log(typeof o.__proto__));
|
||||
}
|
||||
expect_stdout: "object"
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ statements: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -25,6 +27,8 @@ statements_funs: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -48,6 +52,8 @@ sequences: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -71,6 +77,8 @@ sequences_funs: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -108,7 +116,8 @@ catch_var: {
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
a = "PASS";
|
||||
var a;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -118,6 +127,8 @@ issue_2295: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo(o) {
|
||||
@@ -139,6 +150,7 @@ issue_4487_1: {
|
||||
options = {
|
||||
functions: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
keep_fnames: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
@@ -163,6 +175,7 @@ issue_4487_2: {
|
||||
options = {
|
||||
functions: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
keep_fnames: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
@@ -188,6 +201,7 @@ issue_4487_3: {
|
||||
options = {
|
||||
functions: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
keep_fnames: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
@@ -248,8 +262,7 @@ issue_4517: {
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var a = 2;
|
||||
return (A = a) + typeof !1;
|
||||
return (A = 2) + typeof !1;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "2boolean"
|
||||
@@ -260,6 +273,7 @@ issue_4736: {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
@@ -279,7 +293,7 @@ issue_4736: {
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
0,
|
||||
0;
|
||||
console.log(1 << 30);
|
||||
})();
|
||||
})();
|
||||
@@ -291,6 +305,7 @@ issue_4839: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
@@ -317,6 +332,7 @@ issue_4859: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
keep_infinity: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
@@ -441,7 +457,7 @@ issue_4898: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5187: {
|
||||
issue_5187_1: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
hoist_vars: true,
|
||||
@@ -459,6 +475,37 @@ issue_5187: {
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var a, b;
|
||||
a = 42;
|
||||
do {
|
||||
b = { 0: a++ };
|
||||
} while (console.log(b[b ^= 0]));
|
||||
})();
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5187_2: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a = 42;
|
||||
do {
|
||||
var b = { 0: a++ };
|
||||
} while (console.log(b[b ^= 0]));
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var b, a = 42;
|
||||
@@ -547,9 +594,9 @@ issue_5411_1: {
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b, c, a = "PASS";
|
||||
var a, b, c;
|
||||
b++;
|
||||
b = a;
|
||||
b = a = "PASS";
|
||||
c = c && c[b];
|
||||
console.log(b);
|
||||
}
|
||||
@@ -577,7 +624,7 @@ issue_5411_2: {
|
||||
var b, c;
|
||||
b++;
|
||||
b = "PASS",
|
||||
c = c && c[b];
|
||||
c;
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -596,6 +643,30 @@ issue_5411_3: {
|
||||
var a = A = a;
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
a = console;
|
||||
a = A = ++a;
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
issue_5411_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = console;
|
||||
a++;
|
||||
var a = A = a;
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
var a = console;
|
||||
a = A = ++a;
|
||||
@@ -603,3 +674,130 @@ issue_5411_3: {
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
issue_5626: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = function() {
|
||||
return console.log(arguments[0]), 42;
|
||||
}("PASS") ? null : "foo";
|
||||
for (var b in a)
|
||||
FAIL;
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
console.log(arguments[0]);
|
||||
}("PASS"));
|
||||
for (var b in null)
|
||||
FAIL;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5638_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
var a = [ 42 ];
|
||||
console || FAIL(a);
|
||||
console.log(a++);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
a = "FAIL";
|
||||
a = [ 42 ];
|
||||
console || FAIL(a);
|
||||
console.log(a++);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5638_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
var a = [ 6 ];
|
||||
console || FAIL(a);
|
||||
console.log(a *= 7);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
a = "FAIL";
|
||||
a = [ 6 ];
|
||||
console || FAIL(a);
|
||||
console.log(a *= 7);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5638_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var o = { foo: 42 };
|
||||
for (var k in o) {
|
||||
var v = o[k];
|
||||
log(k || v, v++);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var log, o, k, v;
|
||||
log = console.log;
|
||||
for (k in o = { foo: 42 }) {
|
||||
v = o[k];
|
||||
log(k || v, v++);
|
||||
}
|
||||
}
|
||||
expect_stdout: "foo 42"
|
||||
}
|
||||
|
||||
issue_5638_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var o = { foo: 6 };
|
||||
for (var k in o) {
|
||||
var v = o[k];
|
||||
log(k || v, v *= 7);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var log, o, k, v;
|
||||
log = console.log;
|
||||
for (k in o = { foo: 6 }) {
|
||||
v = o[k];
|
||||
log(k || v, v *= 7);
|
||||
}
|
||||
}
|
||||
expect_stdout: "foo 42"
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,17 @@ default_keys: {
|
||||
expect_exact: 'import foo,{bar}from"baz";'
|
||||
}
|
||||
|
||||
non_identifiers: {
|
||||
beautify = {
|
||||
quote_style: 3,
|
||||
}
|
||||
input: {
|
||||
import { '42' as foo } from "bar";
|
||||
import { "foo" as bar } from 'baz';
|
||||
}
|
||||
expect_exact: "import{'42'as foo}from\"bar\";import{foo as bar}from'baz';"
|
||||
}
|
||||
|
||||
dynamic: {
|
||||
input: {
|
||||
(async a => await import(a))("foo").then(bar);
|
||||
@@ -227,3 +238,33 @@ issue_4708_2: {
|
||||
import a from "foo";
|
||||
}
|
||||
}
|
||||
|
||||
pr_5550_1: {
|
||||
input: {
|
||||
if (console)
|
||||
import("foo");
|
||||
else
|
||||
import.meta.url.replace(/bar/g, console.log);
|
||||
}
|
||||
expect: {
|
||||
if (console)
|
||||
import("foo");
|
||||
else
|
||||
import.meta.url.replace(/bar/g, console.log);
|
||||
}
|
||||
}
|
||||
|
||||
pr_5550_2: {
|
||||
input: {
|
||||
L: {
|
||||
import("foo");
|
||||
import.meta.url.replace(/bar/g, console.log);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
L: {
|
||||
import("foo");
|
||||
import.meta.url.replace(/bar/g, console.log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,14 @@ mangle_props: {
|
||||
);
|
||||
}
|
||||
expect_stdout: "1 1 1 2 2 2 3 3 3 4 4 4 5 5"
|
||||
expect_warnings: [
|
||||
"INFO: Preserving reserved property undefined",
|
||||
"INFO: Preserving reserved property NaN",
|
||||
"INFO: Preserving reserved property Infinity",
|
||||
"INFO: Preserving reserved property -Infinity",
|
||||
"INFO: Preserving reserved property null",
|
||||
"INFO: Preserving reserved property log",
|
||||
]
|
||||
}
|
||||
|
||||
numeric_literal: {
|
||||
@@ -106,11 +114,18 @@ numeric_literal: {
|
||||
"4 5 4 4",
|
||||
"8 7 8",
|
||||
]
|
||||
expect_warnings: [
|
||||
"INFO: Preserving reserved property log",
|
||||
"INFO: Mapping property 0x25 to o",
|
||||
"INFO: Mapping property 1E42 to b",
|
||||
]
|
||||
}
|
||||
|
||||
identifier: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
properties: {
|
||||
builtins: true,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var obj = {
|
||||
@@ -209,37 +224,37 @@ identifier: {
|
||||
B: 28,
|
||||
C: 29,
|
||||
D: 30,
|
||||
F: 31,
|
||||
G: 32,
|
||||
false: 33,
|
||||
null: 34,
|
||||
true: 35,
|
||||
H: 36,
|
||||
I: 37,
|
||||
J: 38,
|
||||
K: 39,
|
||||
L: 40,
|
||||
M: 41,
|
||||
N: 42,
|
||||
O: 43,
|
||||
P: 44,
|
||||
Q: 45,
|
||||
R: 46,
|
||||
S: 47,
|
||||
T: 48,
|
||||
U: 49,
|
||||
V: 50,
|
||||
W: 51,
|
||||
X: 52,
|
||||
Y: 53,
|
||||
Z: 54,
|
||||
$: 55,
|
||||
_: 56,
|
||||
ee: 57,
|
||||
te: 58,
|
||||
ne: 59,
|
||||
ae: 60,
|
||||
ie: 61,
|
||||
E: 31,
|
||||
F: 32,
|
||||
G: 33,
|
||||
H: 34,
|
||||
I: 35,
|
||||
J: 36,
|
||||
K: 37,
|
||||
L: 38,
|
||||
M: 39,
|
||||
N: 40,
|
||||
O: 41,
|
||||
P: 42,
|
||||
Q: 43,
|
||||
R: 44,
|
||||
S: 45,
|
||||
T: 46,
|
||||
U: 47,
|
||||
V: 48,
|
||||
W: 49,
|
||||
X: 50,
|
||||
Y: 51,
|
||||
Z: 52,
|
||||
$: 53,
|
||||
_: 54,
|
||||
ee: 55,
|
||||
te: 56,
|
||||
ne: 57,
|
||||
ae: 58,
|
||||
ie: 59,
|
||||
oe: 60,
|
||||
re: 61,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ safe_undefined: {
|
||||
}
|
||||
|
||||
negate_iife_3: {
|
||||
expression = true
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
@@ -123,6 +124,7 @@ negate_iife_3: {
|
||||
}
|
||||
|
||||
negate_iife_3_off: {
|
||||
expression = true
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
@@ -203,6 +205,7 @@ negate_iife_5_off: {
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_true: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
inline: true,
|
||||
@@ -215,11 +218,12 @@ issue_1254_negate_iife_true: {
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: 'void console.log("test");'
|
||||
expect_exact: 'void console.log("test")'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_nested: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
inline: true,
|
||||
@@ -232,7 +236,7 @@ issue_1254_negate_iife_nested: {
|
||||
};
|
||||
})()()()()();
|
||||
}
|
||||
expect_exact: '(void console.log("test"))()()();'
|
||||
expect_exact: '(void console.log("test"))()()()'
|
||||
}
|
||||
|
||||
negate_iife_issue_1073: {
|
||||
|
||||
195
test/compress/issue-5614.js
Normal file
195
test/compress/issue-5614.js
Normal file
@@ -0,0 +1,195 @@
|
||||
record_update: {
|
||||
options = {
|
||||
loops: true,
|
||||
passes: 3,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var value = { a: 42, b: "PASS" };
|
||||
var unused = _Utils_update(value, { b: "FAIL" });
|
||||
function _Utils_update(oldRecord, updatedFields) {
|
||||
var newRecord = {};
|
||||
for (var key in oldRecord)
|
||||
newRecord[key] = oldRecord[key];
|
||||
for (var key in updatedFields)
|
||||
newRecord[key] = updatedFields[key];
|
||||
return newRecord;
|
||||
}
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
currying: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function F(arity, fun, wrapper) {
|
||||
wrapper.a = arity;
|
||||
wrapper.f = fun;
|
||||
return wrapper;
|
||||
}
|
||||
function F2(fun) {
|
||||
return F(2, fun, function(a) {
|
||||
return function(b) {
|
||||
return fun(a, b);
|
||||
};
|
||||
});
|
||||
}
|
||||
function _Utils_eq(x, y) {
|
||||
var pair, stack = [], isEqual = _Utils_eqHelp(x, y, 0, stack);
|
||||
while (isEqual && (pair = stack.pop()))
|
||||
isEqual = _Utils_eqHelp(pair.a, pair.b, 0, stack);
|
||||
return isEqual;
|
||||
}
|
||||
var _Utils_equal = F2(_Utils_eq);
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
conditional_property_write: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var o = {};
|
||||
if (a)
|
||||
o.p = console.log("foo");
|
||||
else
|
||||
o.q = console.log("bar");
|
||||
o.r = console.log("baz");
|
||||
}
|
||||
f(42);
|
||||
f(null);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
if (a)
|
||||
console.log("foo");
|
||||
else
|
||||
console.log("bar");
|
||||
console.log("baz");
|
||||
}
|
||||
f(42);
|
||||
f(null);
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
}
|
||||
|
||||
reassign_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS", b = "FAIL";
|
||||
(b = a).toString();
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b = "FAIL";
|
||||
(b = "PASS").toString();
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
reassign_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
if (false) {
|
||||
a = null + 0;
|
||||
a();
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
if (false) {
|
||||
a = 0;
|
||||
a();
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
reassign_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
(a = a || "PASS").toString();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
(a = (0, "PASS")).toString();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
retain_instance_write: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a;
|
||||
}
|
||||
function g() {
|
||||
var o = {};
|
||||
var b = new f(o);
|
||||
if (console)
|
||||
b.p = "PASS";
|
||||
return o;
|
||||
}
|
||||
console.log(g().p);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return a;
|
||||
}
|
||||
function g() {
|
||||
var o = {};
|
||||
var b = new f(o);
|
||||
if (console)
|
||||
b.p = "PASS";
|
||||
return o;
|
||||
}
|
||||
console.log(g().p);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -68,6 +68,7 @@ drop_console_2: {
|
||||
}
|
||||
|
||||
drop_value: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
side_effects: true,
|
||||
@@ -106,6 +107,7 @@ wrongly_optimized: {
|
||||
}
|
||||
|
||||
negate_iife_1: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
@@ -119,6 +121,7 @@ negate_iife_1: {
|
||||
}
|
||||
|
||||
negate_iife_3: {
|
||||
expression = true
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
@@ -133,6 +136,7 @@ negate_iife_3: {
|
||||
}
|
||||
|
||||
negate_iife_3_off: {
|
||||
expression = true
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
@@ -215,6 +219,7 @@ negate_iife_5_off: {
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_true: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
@@ -226,11 +231,12 @@ issue_1254_negate_iife_true: {
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: '(function(){return function(){console.log("test")}})()();'
|
||||
expect_exact: 'function(){return function(){console.log("test")}}()()'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_nested: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
@@ -242,7 +248,7 @@ issue_1254_negate_iife_nested: {
|
||||
};
|
||||
})()()()()();
|
||||
}
|
||||
expect_exact: '(function(){return function(){console.log("test")}})()()()()();'
|
||||
expect_exact: 'function(){return function(){console.log("test")}}()()()()()'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,11 @@ dont_reuse_prop: {
|
||||
console.log(obj.a);
|
||||
}
|
||||
expect_stdout: "123"
|
||||
expect_warnings: [
|
||||
"INFO: Preserving excluded property a",
|
||||
"INFO: Preserving reserved property log",
|
||||
"INFO: Mapping property asd to b",
|
||||
]
|
||||
}
|
||||
|
||||
unmangleable_props_should_always_be_reserved: {
|
||||
@@ -42,4 +47,9 @@ unmangleable_props_should_always_be_reserved: {
|
||||
console.log(obj.a);
|
||||
}
|
||||
expect_stdout: "123"
|
||||
expect_warnings: [
|
||||
"INFO: Preserving excluded property a",
|
||||
"INFO: Preserving reserved property log",
|
||||
"INFO: Mapping property asd to b",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
keep_var_for_in: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(obj){
|
||||
(function(obj) {
|
||||
var foo = 5;
|
||||
for (var i in obj)
|
||||
return foo;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(obj){
|
||||
(function(obj) {
|
||||
var i, foo = 5;
|
||||
for (i in obj)
|
||||
return foo;
|
||||
|
||||
@@ -111,6 +111,7 @@ labels_5: {
|
||||
labels_6: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
out: break out;
|
||||
@@ -208,6 +209,59 @@ labels_10: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
labels_11: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
L: if (console.log("PASS"))
|
||||
break L;
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
labels_12: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
L: try {
|
||||
if (console.log("foo"))
|
||||
break L;
|
||||
throw "bar";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
break L;
|
||||
} finally {
|
||||
if (console.log("baz"))
|
||||
break L;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
L: try {
|
||||
if (!console.log("foo"))
|
||||
throw "bar";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
if (console.log("baz"))
|
||||
break L;
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
}
|
||||
|
||||
issue_4466_1: {
|
||||
mangle = {
|
||||
v8: false,
|
||||
@@ -327,3 +381,53 @@ issue_4466_2_toplevel_v8: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5522: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
L: try {
|
||||
return "FAIL";
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
return "PASS";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
L: try {
|
||||
return "FAIL";
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
return "PASS";
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5524: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
L: try {
|
||||
FAIL;
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
L: try {
|
||||
FAIL;
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -190,6 +190,96 @@ if_dead_branch: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
retain_tail_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
let b = "bar";
|
||||
while (console.log("baz"));
|
||||
console.log(b);
|
||||
} else {
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
let b = "bar";
|
||||
while (console.log("baz"));
|
||||
console.log(b);
|
||||
} else {
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
retain_tail_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
} else {
|
||||
let b = "baz";
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
} else {
|
||||
let b = "baz";
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"baz",
|
||||
"bar",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
merge_vars_1: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
@@ -892,6 +982,40 @@ if_return_2: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
if_return_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
let b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
let b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
do_if_continue_1: {
|
||||
options = {
|
||||
if_return: true,
|
||||
@@ -1625,7 +1749,7 @@ issue_4438: {
|
||||
function f() {
|
||||
if (console) {
|
||||
let a = console.log;
|
||||
void a("PASS");
|
||||
a("PASS");
|
||||
}
|
||||
}
|
||||
f();
|
||||
@@ -1998,3 +2122,51 @@ issue_5476: {
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5591: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
switch (console.log("foo")) {
|
||||
case console.log("bar"):
|
||||
if (console.log("baz"))
|
||||
return;
|
||||
else {
|
||||
let a;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
switch (console.log("foo")) {
|
||||
case console.log("bar"):
|
||||
if (console.log("baz"))
|
||||
return;
|
||||
else {
|
||||
let a;
|
||||
return;
|
||||
}
|
||||
case null:
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -308,6 +308,7 @@ issue_4679: {
|
||||
issue_5266: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
[
|
||||
|
||||
@@ -206,6 +206,7 @@ mangle_unquoted_properties: {
|
||||
}
|
||||
mangle = {
|
||||
properties: {
|
||||
builtins: true,
|
||||
keep_quoted: true,
|
||||
},
|
||||
}
|
||||
@@ -305,6 +306,7 @@ mangle_debug_suffix_keep_quoted: {
|
||||
}
|
||||
mangle = {
|
||||
properties: {
|
||||
builtins: true,
|
||||
debug: "XYZ",
|
||||
keep_quoted: true,
|
||||
reserved: [],
|
||||
@@ -351,6 +353,68 @@ mangle_debug_suffix_keep_quoted: {
|
||||
}
|
||||
}
|
||||
|
||||
keep_substituted_property: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
mangle = {
|
||||
properties: {
|
||||
keep_quoted: true,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var o = { p: [] };
|
||||
function f(b) {
|
||||
return o[b];
|
||||
}
|
||||
function g() {
|
||||
var a = "p";
|
||||
return o[a] === f(a);
|
||||
}
|
||||
console.log(g() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var o = { p: [] };
|
||||
function f(n) {
|
||||
return o[n];
|
||||
}
|
||||
function g() {
|
||||
var n = "p";
|
||||
return o.p === f(n);
|
||||
}
|
||||
console.log(g() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
keep_substituted_property_quotes: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
beautify = {
|
||||
keep_quoted_props: true,
|
||||
}
|
||||
input: {
|
||||
function f(o) {
|
||||
var a = "p";
|
||||
return o[a];
|
||||
}
|
||||
console.log(f({ p: "PASS" }));
|
||||
}
|
||||
expect: {
|
||||
function f(o) {
|
||||
var a = "p";
|
||||
return o["p"];
|
||||
}
|
||||
console.log(f({ p: "PASS" }));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
first_256_chars_as_properties: {
|
||||
beautify = {
|
||||
ascii_only: true,
|
||||
@@ -897,12 +961,15 @@ issue_2256: {
|
||||
},
|
||||
}
|
||||
input: {
|
||||
({ "keep": 1 });
|
||||
g.keep = g.change;
|
||||
({ "keep": 42 });
|
||||
global.keep = global.change;
|
||||
console.log(keep);
|
||||
}
|
||||
expect: {
|
||||
g.keep = g.g;
|
||||
global.keep = global.l;
|
||||
console.log(keep);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
lhs_prop_1: {
|
||||
|
||||
@@ -147,7 +147,7 @@ relational: {
|
||||
"bar" >= "bar";
|
||||
}
|
||||
expect: {
|
||||
bar();
|
||||
0 instanceof bar();
|
||||
bar();
|
||||
bar(), bar();
|
||||
bar();
|
||||
|
||||
@@ -1540,10 +1540,12 @@ this_toString: {
|
||||
issue_4803: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
|
||||
@@ -2488,7 +2488,7 @@ side_effects_assign: {
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = typeof void (a && a.in);
|
||||
var a = "undefined";
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
@@ -2530,7 +2530,8 @@ pure_getters_2: {
|
||||
var a = a && a.b;
|
||||
}
|
||||
expect: {
|
||||
var a = a && a.b;
|
||||
var a;
|
||||
a && a.b;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5424,7 +5425,7 @@ issue_2774: {
|
||||
get a() {
|
||||
var b;
|
||||
(b = true) && b.c;
|
||||
b = void 0;
|
||||
void 0;
|
||||
}
|
||||
}.a);
|
||||
}
|
||||
@@ -7896,3 +7897,33 @@ issue_5434: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5623: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
function f() {
|
||||
var b = a;
|
||||
a = b;
|
||||
}
|
||||
f && f((a++ && a).toString());
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
function f() {
|
||||
var b;
|
||||
a = a;
|
||||
}
|
||||
f((a++ && a).toString());
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
@@ -50,6 +50,22 @@ regexp_properties: {
|
||||
expect_stdout: "abc true false 0 false"
|
||||
}
|
||||
|
||||
instanceof_1: {
|
||||
input: {
|
||||
console.log(/foo/ instanceof RegExp);
|
||||
}
|
||||
expect_exact: "console.log(/foo/ instanceof RegExp);"
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
instanceof_2: {
|
||||
input: {
|
||||
console.log(42 + /foo/ instanceof Object);
|
||||
}
|
||||
expect_exact: "console.log(42+/foo/ instanceof Object);"
|
||||
expect_stdout: "false"
|
||||
}
|
||||
|
||||
issue_3434_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
|
||||
@@ -648,7 +648,7 @@ drop_new_function: {
|
||||
}
|
||||
expect: {
|
||||
void ([ ... {
|
||||
[console.log("PASS")]: [].e,
|
||||
[console.log("PASS")]: [][0],
|
||||
}] = []);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -1363,3 +1363,264 @@ issue_5391: {
|
||||
expect_stdout: "NaN"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_5533_1_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_1_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...[ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...[ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5552_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var a = f, b = log();
|
||||
function f(...[ c = a = "PASS" ]) {}
|
||||
f((a = "FAIL", b));
|
||||
log(a);
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var a = f, b = log();
|
||||
function f(...[ c = a = "PASS" ]) {}
|
||||
f((a = "FAIL", b));
|
||||
log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5552_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var a = f;
|
||||
function f(...{ [a = "PASS"]: b }) {}
|
||||
f((a = "FAIL", 42));
|
||||
log(a);
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var a = f;
|
||||
function f(...{ [a = "PASS"]: b }) {}
|
||||
f((a = "FAIL", 42));
|
||||
log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5552_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ "FAIL", "PASS" ];
|
||||
console.log(function(b, ...[ c = a.pop() ]) {
|
||||
return b;
|
||||
}(a.pop()));
|
||||
}
|
||||
expect: {
|
||||
var a = [ "FAIL", "PASS" ];
|
||||
console.log(function(b, ...[ c = a.pop() ]) {
|
||||
return b;
|
||||
}(a.pop()));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5552_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ "FAIL", "PASS" ];
|
||||
console.log(function(b, ...{ [a.pop()]: c }) {
|
||||
return b;
|
||||
}(a.pop()));
|
||||
}
|
||||
expect: {
|
||||
var a = [ "FAIL", "PASS" ];
|
||||
console.log(function(b, ...{ [a.pop()]: c }) {
|
||||
return b;
|
||||
}(a.pop()));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -318,6 +318,32 @@ unsafe_string_replace: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
unsafe_Object_call: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
f: function(a) {
|
||||
console.log(a ? this.p : "FAIL 1");
|
||||
},
|
||||
p: "FAIL 2",
|
||||
}, p = "PASS";
|
||||
Object(o.f)(42);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
f: function(a) {
|
||||
console.log(a ? this.p : "FAIL 1");
|
||||
},
|
||||
p: "FAIL 2",
|
||||
}, p = "PASS";
|
||||
(0, o.f)(42);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
drop_value: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
@@ -645,3 +671,56 @@ issue_4751: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
drop_instanceof: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
42 instanceof function() {};
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
drop_instanceof_reference: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
42 instanceof f;
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
retain_instanceof: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
42 instanceof "foo";
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
0 instanceof "foo";
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
decimal: {
|
||||
input: {
|
||||
console.log({... 0.42});
|
||||
}
|
||||
expect_exact: "console.log({....42});"
|
||||
expect_stdout: "{}"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
collapse_vars_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -1194,3 +1203,53 @@ issue_5382: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_5602: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
sequences: true,
|
||||
spreads: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
try {
|
||||
var b = function(c) {
|
||||
if (c)
|
||||
return FAIL;
|
||||
var d = 42;
|
||||
}(...[ null, A = 0 ]);
|
||||
} catch (e) {
|
||||
b();
|
||||
}
|
||||
})();
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
try {
|
||||
var b = void (A = 0);
|
||||
} catch (e) {
|
||||
b();
|
||||
}
|
||||
})(),
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
expect_warnings: [
|
||||
"INFO: Dropping unused variable d [test/compress/spreads.js:6,24]",
|
||||
"INFO: Collapsing c [test/compress/spreads.js:4,24]",
|
||||
"INFO: Dropping unused variable c [test/compress/spreads.js:3,33]",
|
||||
"INFO: pass 0: last_count: Infinity, count: 27",
|
||||
"WARN: Condition always false [test/compress/spreads.js:4,20]",
|
||||
"INFO: Collapsing null [test/compress/spreads.js:7,23]",
|
||||
"INFO: Collapsing 0 [test/compress/spreads.js:3,24]",
|
||||
"INFO: pass 1: last_count: 27, count: 22",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -1608,3 +1608,83 @@ issue_5012: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5543_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
switch (a) {
|
||||
default:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("PASS"):
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
switch (false) {
|
||||
case a:
|
||||
case console.log("FAIL"):
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
switch (a) {
|
||||
default:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("PASS"):
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
switch (false) {
|
||||
case a:
|
||||
case console.log("FAIL"):
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5543_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
switch (a) {
|
||||
default:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("PASS"):
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("FAIL"):
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
switch (a) {
|
||||
default:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("PASS"):
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("FAIL"):
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ if_return: {
|
||||
if (w) {
|
||||
if (y) return;
|
||||
} else if (z) return;
|
||||
return x == y || (x && w(), y && z()), !0;
|
||||
return x != y && (x && w(), y && z()), !0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,6 +194,43 @@ scope_adjustment_let: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
escaped_const: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
const log = console.log;
|
||||
log("PASS");
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
escaped_let: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
let log = console.log;
|
||||
log("PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var log = console.log;
|
||||
log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4191_const: {
|
||||
options = {
|
||||
functions: true,
|
||||
@@ -613,3 +650,35 @@ issue_4954: {
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5516: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(typeof function() {
|
||||
{
|
||||
let a;
|
||||
}
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(typeof function() {
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -907,7 +907,7 @@ drop_body: {
|
||||
})([ console.log("baz") ]);
|
||||
}
|
||||
expect: {
|
||||
[ [ , [].e = console.log("foo") ] ] = [ [ console.log("baz") ] ];
|
||||
[ [ , [][0] = console.log("foo") ] ] = [ [ console.log("baz") ] ];
|
||||
}
|
||||
expect_stdout: [
|
||||
"baz",
|
||||
@@ -934,6 +934,21 @@ drop_unused_call: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
instanceof_lambda: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(42 instanceof function*() {});
|
||||
}
|
||||
expect: {
|
||||
console.log(false);
|
||||
}
|
||||
expect_stdout: "false"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4454_1: {
|
||||
rename = false
|
||||
options = {
|
||||
@@ -1168,6 +1183,35 @@ issue_4641_2: {
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_4641_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof async function*() {
|
||||
try {
|
||||
return void "FAIL";
|
||||
} finally {
|
||||
console.log("PASS");
|
||||
}
|
||||
}().next().then);
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof async function*() {
|
||||
try {
|
||||
return void "FAIL";
|
||||
} finally {
|
||||
console.log("PASS");
|
||||
}
|
||||
}().next().then);
|
||||
}
|
||||
expect_stdout: [
|
||||
"function",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_4769_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
@@ -1452,6 +1496,80 @@ issue_5385_2: {
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5385_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
return function() {
|
||||
try {
|
||||
throw console.log("foo");
|
||||
} catch (e) {
|
||||
return console.log("bar");
|
||||
}
|
||||
}();
|
||||
})().next();
|
||||
console.log("moo");
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
try {
|
||||
throw console.log("foo");
|
||||
} catch (e) {
|
||||
return console.log("bar");
|
||||
}
|
||||
return void 0;
|
||||
})().next();
|
||||
console.log("moo");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"moo",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5385_4: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
resolve(console.log("FAIL"));
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
return "PASS";
|
||||
}
|
||||
}();
|
||||
})().next().then(o => console.log(o.value, o.done));
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
resolve(console.log("FAIL"));
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
return "PASS";
|
||||
}
|
||||
}();
|
||||
})().next().then(o => console.log(o.value, o.done));
|
||||
}
|
||||
expect_stdout: "PASS true"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5425: {
|
||||
options = {
|
||||
assignments: true,
|
||||
@@ -1515,3 +1633,139 @@ issue_5456: {
|
||||
expect_stdout: "foo"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5506: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
var b = function*() {
|
||||
a = null in (a = "PASS");
|
||||
}();
|
||||
try {
|
||||
b.next();
|
||||
} catch (e) {
|
||||
return a;
|
||||
}
|
||||
}("FAIL"));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
var b = function*() {
|
||||
a = null in (a = "PASS");
|
||||
}();
|
||||
try {
|
||||
b.next();
|
||||
} catch (e) {
|
||||
return a;
|
||||
}
|
||||
}("FAIL"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5526: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
try {
|
||||
return function() {
|
||||
while (console.log("foo"));
|
||||
}();
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
try {
|
||||
while (console.log("foo"));
|
||||
return void 0;
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5576: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
try {
|
||||
(function() {
|
||||
while (console.log("foo"));
|
||||
})();
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
try {
|
||||
while (console.log("foo"));
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5663: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var [ , a ] = function*() {
|
||||
console.log("foo");
|
||||
yield console.log("bar");
|
||||
console.log("baz");
|
||||
yield console.log("moo");
|
||||
console.log("moz");
|
||||
yield FAIL;
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
var [ , , ] = function*() {
|
||||
console.log("foo");
|
||||
yield console.log("bar");
|
||||
console.log("baz");
|
||||
yield console.log("moo");
|
||||
console.log("moz");
|
||||
yield FAIL;
|
||||
}();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
"moo",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -38,4 +38,4 @@ var _require = require("bar"), foo = _require.foo;
|
||||
var _require2 = require("world"), hello = _require2.hello;
|
||||
|
||||
foo.x.apply(foo, _toConsumableArray(foo.y(hello.z)));
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImlucHV0LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHtmb299ID0gcmVxdWlyZShcImJhclwiKTtcbmNvbnN0IHtoZWxsb30gPSByZXF1aXJlKFwid29ybGRcIik7XG5cbmZvby54KC4uLmZvby55KGhlbGxvLnopKTtcbiJdLCJuYW1lcyI6WyJyZXF1aXJlIiwiZm9vIiwiaGVsbG8iLCJ4IiwiYXBwbHkiLCJfdG9Db25zdW1hYmxlQXJyYXkiLCJ5IiwieiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7ZUFBY0EsUUFBUSxRQUFmQyxNLFNBQUFBOztBLGdCQUNTRCxRQUFRLFVBQWpCRSxRLFVBQUFBOztBQUVQRCxJQUFJRSxFQUFKQyxNQUFBSCxLQUFHSSxtQkFBTUosSUFBSUssRUFBRUosTUFBTUsifQ==
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImlucHV0LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHtmb299ID0gcmVxdWlyZShcImJhclwiKTtcbmNvbnN0IHtoZWxsb30gPSByZXF1aXJlKFwid29ybGRcIik7XG5cbmZvby54KC4uLmZvby55KGhlbGxvLnopKTtcbiJdLCJuYW1lcyI6WyJyZXF1aXJlIiwiZm9vIiwiaGVsbG8iLCJ4IiwiYXBwbHkiLCJfdG9Db25zdW1hYmxlQXJyYXkiLCJ5IiwieiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7ZUFBY0EsUUFBUSxLQUFELEdBQWRDLE0sU0FBQUE7O0EsZ0JBQ1NELFFBQVEsT0FBRCxHQUFoQkUsUSxVQUFBQTs7QUFFUEQsSUFBSUUsRUFBSkMsTUFBQUgsS0FBR0ksbUJBQU1KLElBQUlLLEVBQUVKLE1BQU1LLENBQVosQ0FBTixDQUFBIn0=
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
console.log(3);
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSJ9
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSxDQUFHIn0=
|
||||
|
||||
@@ -2,4 +2,4 @@ function test(a){
|
||||
"aaaaaaaaaaaaaaaa";
|
||||
a(err,data),a(err,
|
||||
data)}
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsidGVzdCIsImNhbGxiYWNrIiwiZXJyIiwiZGF0YSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0E7SEFBS0M7QUFFVkE7aEJBQVNDLElBQUtDLE1BQ2RGLEVBQVNDLElBQUtDIn0=
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsidGVzdCIsImNhbGxiYWNrIiwiZXJyIiwiZGF0YSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0E7SEFBS0MsR0FDVjtBQUNBQTtoQkFBU0MsSUFBS0MsSUFBSSxFQUNsQkYsRUFBU0MsSUFBS0MsSUFBSSxDQUN0QiJ9
|
||||
@@ -1,2 +1,2 @@
|
||||
console.log(3);
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSJ9
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSxDQUFHIn0=
|
||||
|
||||
@@ -62,6 +62,7 @@ if (typeof phantom == "undefined") {
|
||||
var cmd = process.platform == "win32" ? "npm.cmd" : "npm";
|
||||
|
||||
function npm(args, done) {
|
||||
args.push("--loglevel=error");
|
||||
child_process.spawn(cmd, args, { stdio: [ "ignore", 1, 2 ] }).on("exit", done);
|
||||
}
|
||||
|
||||
@@ -72,9 +73,12 @@ if (typeof phantom == "undefined") {
|
||||
"is-my-json-valid@2.20.5",
|
||||
"phantomjs-prebuilt@2.1.14",
|
||||
"--no-audit",
|
||||
"--no-fund",
|
||||
"--no-optional",
|
||||
"--no-save",
|
||||
"--no-strict-ssl",
|
||||
"--no-update-notifier",
|
||||
"--production",
|
||||
], function(code) {
|
||||
if (code) {
|
||||
console.log("npm install failed with code", code);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
var fs = require("fs");
|
||||
|
||||
var config = {
|
||||
limit: 10000,
|
||||
timeout: function(limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
this.limit = limit + lag;
|
||||
},
|
||||
};
|
||||
var lag = +process.env["UGLIFY_GITHUB_LAG"] || 0;
|
||||
var tasks = [];
|
||||
var titles = [];
|
||||
config.timeout(10000);
|
||||
describe = function(title, fn) {
|
||||
config = Object.create(config);
|
||||
titles.push(title);
|
||||
@@ -21,10 +22,11 @@ it = function(title, fn) {
|
||||
fn.titles.push(title);
|
||||
tasks.push(fn);
|
||||
};
|
||||
|
||||
fs.readdirSync("test/mocha").filter(function(file) {
|
||||
return /\.js$/.test(file);
|
||||
}).forEach(function(file) {
|
||||
(function(arg) {
|
||||
return arg ? [ arg ] : fs.readdirSync("test/mocha").filter(function(file) {
|
||||
return /\.js$/.test(file);
|
||||
});
|
||||
})(process.argv[2]).forEach(function(file) {
|
||||
require("./mocha/" + file);
|
||||
});
|
||||
|
||||
@@ -66,12 +68,13 @@ process.nextTick(function run() {
|
||||
if (task.length) {
|
||||
task.timeout = function(limit) {
|
||||
clearTimeout(timer);
|
||||
limit += lag;
|
||||
task.limit = limit;
|
||||
timer = setTimeout(function() {
|
||||
raise(new Error("Timed out: exceeds " + limit + "ms"));
|
||||
}, limit);
|
||||
};
|
||||
task.timeout(task.limit);
|
||||
task.timeout(task.limit - lag);
|
||||
process.on("uncaughtException", raise);
|
||||
task.call(task, done);
|
||||
} else {
|
||||
|
||||
@@ -53,6 +53,23 @@ describe("bin/uglifyjs", function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should work with --expression", function(done) {
|
||||
exec([
|
||||
uglifyjscmd,
|
||||
"--expression",
|
||||
"--compress",
|
||||
"--mangle",
|
||||
].join(" "), function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function(n){for(;n(););return 42}(A)\n");
|
||||
done();
|
||||
}).stdin.end([
|
||||
"function(x) {",
|
||||
" while (x()) {}",
|
||||
" return 42;",
|
||||
"}(A)",
|
||||
].join("\n"));
|
||||
});
|
||||
it("Should work with --source-map names=true", function(done) {
|
||||
exec([
|
||||
uglifyjscmd,
|
||||
@@ -69,7 +86,7 @@ describe("bin/uglifyjs", function() {
|
||||
" q: b",
|
||||
"};",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,",
|
||||
].join("\n")
|
||||
].join("\n");
|
||||
assert.strictEqual(stdout.slice(0, expected.length), expected);
|
||||
var map = JSON.parse(to_ascii(stdout.slice(expected.length).trim()));
|
||||
assert.deepEqual(map.names, [ "obj", "p", "a", "q", "b" ]);
|
||||
@@ -97,7 +114,7 @@ describe("bin/uglifyjs", function() {
|
||||
" q: b",
|
||||
"};",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,",
|
||||
].join("\n")
|
||||
].join("\n");
|
||||
assert.strictEqual(stdout.slice(0, expected.length), expected);
|
||||
var map = JSON.parse(to_ascii(stdout.slice(expected.length).trim()));
|
||||
assert.deepEqual(map.names, []);
|
||||
@@ -126,7 +143,7 @@ describe("bin/uglifyjs", function() {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
"var bar=function(){function foo(bar){return bar}return foo}();",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxHQUNYLENBRUEsT0FBT0MsR0FDVixFQUFFIn0=",
|
||||
"",
|
||||
].join("\n"));
|
||||
done();
|
||||
@@ -313,7 +330,7 @@ describe("bin/uglifyjs", function() {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
"var bar=function(){function foo(bar){return bar}return foo}();",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxHQUNYLENBRUEsT0FBT0MsR0FDVixFQUFFIn0=",
|
||||
"",
|
||||
].join("\n"));
|
||||
var stderrLines = stderr.split("\n");
|
||||
@@ -333,7 +350,7 @@ describe("bin/uglifyjs", function() {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
"var Foo=function Foo(){console.log(1+2)};new Foo;var bar=function(){function foo(bar){return bar}return foo}();",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwidGVzdC9pbnB1dC9pc3N1ZS0xMzIzL3NhbXBsZS5qcyJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFNBQUVBLE1BQWNDLFFBQVFDLElBQUksRUFBRSxJQUFPLElBQUlGLElDQW5ELElBQUlHLElBQU0sV0FDTixTQUFTQyxJQUFLRCxLQUNWLE9BQU9BLElBR1gsT0FBT0MsSUFMRCJ9",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwidGVzdC9pbnB1dC9pc3N1ZS0xMzIzL3NhbXBsZS5qcyJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFNBQUVBLE1BQWNDLFFBQVFDLElBQUksRUFBRSxDQUFDLENBQUUsRUFBSSxJQUFJRixJQ0FuRCxJQUFJRyxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxHQUNYLENBRUEsT0FBT0MsR0FDVixFQUFFIn0=",
|
||||
"",
|
||||
].join("\n"));
|
||||
var stderrLines = stderr.split("\n");
|
||||
@@ -774,7 +791,7 @@ describe("bin/uglifyjs", function() {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
'"use strict";var foo=function foo(x){return"foo "+x};console.log(foo("bar"));',
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbImZvbyIsIngiLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiYUFBQSxJQUFJQSxJQUFNLFNBQU5BLElBQU1DLEdBQUEsTUFBSyxPQUFTQSxHQUN4QkMsUUFBUUMsSUFBSUgsSUFBSSJ9",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbImZvbyIsIngiLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiYUFBQSxJQUFJQSxJQUFNLFNBQU5BLElBQU1DLEdBQUEsTUFBSyxPQUFTQSxDQUFkLEVBQ1ZDLFFBQVFDLElBQUlILElBQUksS0FBSixDQUFaIn0=",
|
||||
""
|
||||
].join("\n"));
|
||||
done();
|
||||
@@ -797,7 +814,7 @@ describe("bin/uglifyjs", function() {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
'function foo(){return function(){console.log("PASS")}}foo()();',
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMjMxMC9pbnB1dC5qcyJdLCJuYW1lcyI6WyJmb28iLCJjb25zb2xlIiwibG9nIiwiZiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsTUFDTCxPQUFPLFdBQ0hDLFFBQVFDLElBQUksU0FLUkYsS0FDUkcifQ==",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMjMxMC9pbnB1dC5qcyJdLCJuYW1lcyI6WyJmb28iLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxNQUNMLE9BQU8sV0FDSEMsUUFBUUMsSUFBSSxNQUFNLENBQ3RCLENBQ0osQ0FHWUYsSUFBSSxFQUNWIn0=",
|
||||
""
|
||||
].join("\n"));
|
||||
done();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
var acorn = require("acorn");
|
||||
var assert = require("assert");
|
||||
var UglifyJS = require("../node");
|
||||
|
||||
@@ -25,6 +26,7 @@ describe("export", function() {
|
||||
"export { * };",
|
||||
"export { * as A };",
|
||||
"export { 42 as A };",
|
||||
"export { 'A' as B };",
|
||||
"export { A as B-C };",
|
||||
"export { default as A };",
|
||||
].forEach(function(code) {
|
||||
@@ -51,8 +53,11 @@ describe("export", function() {
|
||||
it("Should reject invalid `export ... from ...` statement syntax", function() {
|
||||
[
|
||||
"export from 'path';",
|
||||
"export A from 'path';",
|
||||
"export * from `path`;",
|
||||
"export 'A' from 'path';",
|
||||
"export A as B from 'path';",
|
||||
"export 'A' as B from 'path';",
|
||||
"export default from 'path';",
|
||||
"export { A }, B from 'path';",
|
||||
"export * as A, B from 'path';",
|
||||
@@ -68,4 +73,109 @@ describe("export", function() {
|
||||
}, code);
|
||||
});
|
||||
});
|
||||
it("Should reject `export` statement not under top-level scope", function() {
|
||||
[
|
||||
"{ export {}; }",
|
||||
"if (0) export var A;",
|
||||
"function f() { export default 42; }",
|
||||
].forEach(function(code) {
|
||||
assert.throws(function() {
|
||||
UglifyJS.parse(code);
|
||||
}, function(e) {
|
||||
return e instanceof UglifyJS.JS_Parse_Error;
|
||||
}, code);
|
||||
});
|
||||
});
|
||||
it("Should compare `export` statements correctly", function() {
|
||||
var stats = {
|
||||
Declaration: [
|
||||
"export let A;",
|
||||
"export const A = 42;",
|
||||
"export var { A, B: [] } = C;",
|
||||
"export function A() { return B(A); }",
|
||||
"export async function* A({}, ...[]) { return B(A); }",
|
||||
],
|
||||
Default: [
|
||||
"export default 42;",
|
||||
"export default A => A(B);",
|
||||
"export default class A extends B {}",
|
||||
"export default (class A extends B {});",
|
||||
"export default class A { static C = 42; }",
|
||||
"export default class A extends B { static C = 42; }",
|
||||
],
|
||||
Foreign: [
|
||||
"export * from 'path';",
|
||||
"export {} from 'path';",
|
||||
"export * as A from 'path';",
|
||||
"export { default } from 'path';",
|
||||
"export { A, B as C } from 'path';",
|
||||
"export { A, default as C } from 'path';",
|
||||
],
|
||||
References: [
|
||||
"export {};",
|
||||
"export { A };",
|
||||
"export { A as B };",
|
||||
"export { A, B as C };",
|
||||
"export { A as default };",
|
||||
],
|
||||
};
|
||||
for (var k in stats) stats[k].forEach(function(c, i) {
|
||||
var s = UglifyJS.parse(c);
|
||||
assert.ok(s instanceof UglifyJS.AST_Toplevel, c);
|
||||
assert.strictEqual(s.body.length, 1, c);
|
||||
assert.strictEqual(s.body[0].TYPE, "Export" + k, c);
|
||||
for (var l in stats) stats[l].forEach(function(d, j) {
|
||||
var t = UglifyJS.parse(d);
|
||||
assert.ok(t instanceof UglifyJS.AST_Toplevel, d);
|
||||
assert.strictEqual(t.body.length, 1, d);
|
||||
assert.strictEqual(t.body[0].TYPE, "Export" + l, d);
|
||||
assert.strictEqual(s.equals(t), k === l && i === j, c + "\n" + d);
|
||||
});
|
||||
});
|
||||
});
|
||||
it("Should interoperate with ESTree correctly", function() {
|
||||
[
|
||||
"export var A = 42;",
|
||||
"export default (class A {});",
|
||||
"var A; export { A as '42' };",
|
||||
"export { '42' } from 'path';",
|
||||
"export * as '42' from 'path';",
|
||||
].forEach(function(code) {
|
||||
var ast = UglifyJS.parse(code);
|
||||
try {
|
||||
var spidermonkey = ast.to_mozilla_ast();
|
||||
} catch (ex) {
|
||||
assert.fail("[to_mozilla_ast] " + ex.stack);
|
||||
}
|
||||
try {
|
||||
var ast2 = UglifyJS.AST_Node.from_mozilla_ast(spidermonkey);
|
||||
} catch (ex) {
|
||||
assert.fail("[from_mozilla_ast] " + ex.stack);
|
||||
}
|
||||
assert.strictEqual(ast2.print_to_string(), ast.print_to_string(), [
|
||||
"spidermonkey:",
|
||||
ast.print_to_string(),
|
||||
ast2.print_to_string(),
|
||||
].join("\n"));
|
||||
try {
|
||||
var acorn_est = acorn.parse(code, {
|
||||
ecmaVersion: "latest",
|
||||
locations: true,
|
||||
sourceType: "module",
|
||||
});
|
||||
} catch (ex) {
|
||||
assert.fail("[acorn.parse] " + ex.stack);
|
||||
}
|
||||
try {
|
||||
var ast3 = UglifyJS.AST_Node.from_mozilla_ast(acorn_est);
|
||||
} catch (ex) {
|
||||
assert.fail("[from_acorn] " + ex.stack);
|
||||
}
|
||||
assert.strictEqual(ast3.print_to_string(), ast.print_to_string(), [
|
||||
"acorn:",
|
||||
ast.print_to_string(),
|
||||
ast3.print_to_string(),
|
||||
].join("\n"));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
var acorn = require("acorn");
|
||||
var assert = require("assert");
|
||||
var UglifyJS = require("../node");
|
||||
|
||||
@@ -8,15 +9,25 @@ describe("import", function() {
|
||||
"import A;",
|
||||
"import {};",
|
||||
"import `path`;",
|
||||
"{ import 'path'; }",
|
||||
"import from 'path';",
|
||||
"if (0) import 'path';",
|
||||
"import * from 'path';",
|
||||
"import 'A' from 'path';",
|
||||
"import A-B from 'path';",
|
||||
"import A as B from 'path';",
|
||||
"import { A }, B from 'path';",
|
||||
"import * as 'A' from 'path';",
|
||||
"import * as A-B from 'path';",
|
||||
"import * as A, B from 'path';",
|
||||
"import * as A, {} from 'path';",
|
||||
"import { * as A } from 'path';",
|
||||
"import { * as 'A' } from 'path';",
|
||||
"import { * as A-B } from 'path';",
|
||||
"function f() { import 'path'; }",
|
||||
"import { 42 as A } from 'path';",
|
||||
"import { A-B as C } from 'path';",
|
||||
"import { 'A' as 'B' } from 'path';",
|
||||
].forEach(function(code) {
|
||||
assert.throws(function() {
|
||||
UglifyJS.parse(code);
|
||||
@@ -25,4 +36,74 @@ describe("import", function() {
|
||||
}, code);
|
||||
});
|
||||
});
|
||||
it("Should compare `import` statements correctly", function() {
|
||||
[
|
||||
"import 'foo';",
|
||||
"import 'path';",
|
||||
"import A from 'path';",
|
||||
"import { A } from 'path';",
|
||||
"import * as A from 'path';",
|
||||
"import A, { B } from 'path';",
|
||||
"import A, * as B from 'path';",
|
||||
"import { A as B } from 'path';",
|
||||
"import A, { B, C as D } from 'path';",
|
||||
].forEach(function(c, i, stats) {
|
||||
var s = UglifyJS.parse(c);
|
||||
assert.ok(s instanceof UglifyJS.AST_Toplevel, c);
|
||||
assert.strictEqual(s.body.length, 1, c);
|
||||
assert.ok(s.body[0] instanceof UglifyJS.AST_Import, c);
|
||||
stats.forEach(function(d, j) {
|
||||
var t = UglifyJS.parse(d);
|
||||
assert.ok(t instanceof UglifyJS.AST_Toplevel, d);
|
||||
assert.strictEqual(t.body.length, 1, d);
|
||||
assert.ok(t.body[0] instanceof UglifyJS.AST_Import, d);
|
||||
assert.strictEqual(s.equals(t), i === j, c + "\n" + d);
|
||||
});
|
||||
});
|
||||
});
|
||||
it("Should interoperate with ESTree correctly", function() {
|
||||
[
|
||||
"import A from 'path';",
|
||||
"import * as A from 'path';",
|
||||
"import A, * as B from 'path';",
|
||||
"import { '42' as A, B } from 'path';",
|
||||
"import A, { '42' as B } from 'path';",
|
||||
].forEach(function(code) {
|
||||
var ast = UglifyJS.parse(code);
|
||||
try {
|
||||
var spidermonkey = ast.to_mozilla_ast();
|
||||
} catch (ex) {
|
||||
assert.fail("[to_mozilla_ast] " + ex.stack);
|
||||
}
|
||||
try {
|
||||
var ast2 = UglifyJS.AST_Node.from_mozilla_ast(spidermonkey);
|
||||
} catch (ex) {
|
||||
assert.fail("[from_mozilla_ast] " + ex.stack);
|
||||
}
|
||||
assert.strictEqual(ast2.print_to_string(), ast.print_to_string(), [
|
||||
"spidermonkey:",
|
||||
ast.print_to_string(),
|
||||
ast2.print_to_string(),
|
||||
].join("\n"));
|
||||
try {
|
||||
var acorn_est = acorn.parse(code, {
|
||||
ecmaVersion: "latest",
|
||||
locations: true,
|
||||
sourceType: "module",
|
||||
});
|
||||
} catch (ex) {
|
||||
assert.fail("[acorn.parse] " + ex.stack);
|
||||
}
|
||||
try {
|
||||
var ast3 = UglifyJS.AST_Node.from_mozilla_ast(acorn_est);
|
||||
} catch (ex) {
|
||||
assert.fail("[from_acorn] " + ex.stack);
|
||||
}
|
||||
assert.strictEqual(ast3.print_to_string(), ast.print_to_string(), [
|
||||
"acorn:",
|
||||
ast.print_to_string(),
|
||||
ast3.print_to_string(),
|
||||
].join("\n"));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
var assert = require("assert");
|
||||
var readFileSync = require("fs").readFileSync;
|
||||
var run_code = require("../sandbox").run_code;
|
||||
var semver = require("semver");
|
||||
var UglifyJS = require("../..");
|
||||
|
||||
function read(path) {
|
||||
@@ -320,6 +321,24 @@ describe("minify", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("module", function() {
|
||||
it("Should not inline `await` variables", function() {
|
||||
if (semver.satisfies(process.version, "<8")) return;
|
||||
var code = [
|
||||
"console.log(function() {",
|
||||
" return typeof await;",
|
||||
"}());",
|
||||
].join("\n");
|
||||
assert.strictEqual(run_code("(async function(){" + code + "})();"), "undefined\n");
|
||||
var result = UglifyJS.minify(code, {
|
||||
module: true,
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, "console.log(function(){return typeof await}());");
|
||||
assert.strictEqual(run_code("(async function(){" + result.code + "})();"), "undefined\n");
|
||||
});
|
||||
});
|
||||
|
||||
describe("rename", function() {
|
||||
it("Should be repeatable", function() {
|
||||
var code = "!function(x){return x(x)}(y);";
|
||||
|
||||
@@ -50,12 +50,10 @@ describe("Number literals", function() {
|
||||
"0.000_000_004_2e+1_0-0B101_010+0x2_A-0o5_2+4_2",
|
||||
].forEach(function(code) {
|
||||
var result = UglifyJS.minify(code, {
|
||||
compress: {
|
||||
expression: true,
|
||||
},
|
||||
expression: true,
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, "42;");
|
||||
assert.strictEqual(result.code, "42");
|
||||
});
|
||||
});
|
||||
it("Should reject invalid use of underscore", function() {
|
||||
|
||||
@@ -449,6 +449,27 @@ describe("test/reduce.js", function() {
|
||||
].join("\n"));
|
||||
});
|
||||
it("Should transform `export default function` correctly", function() {
|
||||
if (semver.satisfies(process.version, "<8")) return;
|
||||
var code = [
|
||||
"export default function f(a) {",
|
||||
" for (var k in a)",
|
||||
" console.log(k);",
|
||||
" (async function() {})();",
|
||||
"}",
|
||||
"f(this);",
|
||||
].join("\n");
|
||||
var result = reduce_test(code, {
|
||||
mangle: false,
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, [
|
||||
"// Can't reproduce test failure",
|
||||
"// minify options: {",
|
||||
'// "mangle": false',
|
||||
"// }",
|
||||
].join("\n"));
|
||||
});
|
||||
it("Should transform `export default (function)` correctly", function() {
|
||||
var code = [
|
||||
"for (var k in this)",
|
||||
" console.log(k);",
|
||||
|
||||
@@ -19,11 +19,11 @@ function source_map(code) {
|
||||
function get_map() {
|
||||
return {
|
||||
"version": 3,
|
||||
"sources": ["index.js"],
|
||||
"sources": [ "index.js" ],
|
||||
"names": [],
|
||||
"mappings": ";;AAAA,IAAI,MAAM,SAAN,GAAM;AAAA,SAAK,SAAS,CAAd;AAAA,CAAV;AACA,QAAQ,GAAR,CAAY,IAAI,KAAJ,CAAZ",
|
||||
"file": "bundle.js",
|
||||
"sourcesContent": ["let foo = x => \"foo \" + x;\nconsole.log(foo(\"bar\"));"]
|
||||
"sourcesContent": [ "let foo = x => \"foo \" + x;\nconsole.log(foo(\"bar\"));" ],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ function prepare_map(sourceMap) {
|
||||
sourceMap: {
|
||||
content: sourceMap,
|
||||
includeSources: true,
|
||||
}
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
return JSON.parse(result.map);
|
||||
@@ -112,7 +112,7 @@ describe("sourcemaps", function() {
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, "class A{static P=42;set#q(s){}}");
|
||||
assert.strictEqual(result.map, '{"version":3,"sources":["0"],"names":["A","P","#q","v"],"mappings":"MAAMA,EACFC,SAAW,GACXC,MAAOC"}');
|
||||
assert.strictEqual(result.map, '{"version":3,"sources":["0"],"names":["A","P","#q","v"],"mappings":"MAAMA,EACFC,SAAW,GACXC,MAAOC,IACX"}');
|
||||
});
|
||||
it("Should mark array/object literals", function() {
|
||||
var result = UglifyJS.minify([
|
||||
@@ -124,7 +124,7 @@ describe("sourcemaps", function() {
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, "({}).wat([]);");
|
||||
assert.strictEqual(result.map, '{"version":3,"sources":["0"],"names":["wat"],"mappings":"CAAU,IACNA,IAAI"}');
|
||||
assert.strictEqual(result.map, '{"version":3,"sources":["0"],"names":["wat"],"mappings":"CAAU,IACNA,IAAI,EAAE"}');
|
||||
});
|
||||
it("Should give correct sourceRoot", function() {
|
||||
var code = "console.log(42);";
|
||||
@@ -135,7 +135,7 @@ describe("sourcemaps", function() {
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, code);
|
||||
assert.strictEqual(result.map, '{"version":3,"sourceRoot":"//foo.bar/","sources":["0"],"names":["console","log"],"mappings":"AAAAA,QAAQC,IAAI"}');
|
||||
assert.strictEqual(result.map, '{"version":3,"sourceRoot":"//foo.bar/","sources":["0"],"names":["console","log"],"mappings":"AAAAA,QAAQC,IAAI,EAAE"}');
|
||||
});
|
||||
it("Should produce same source map with DOS or UNIX line endings", function() {
|
||||
var code = [
|
||||
@@ -160,8 +160,8 @@ describe("sourcemaps", function() {
|
||||
sourceMap: {
|
||||
content: read("test/input/issue-1236/simple.js.map"),
|
||||
filename: "simple.min.js",
|
||||
includeSources: true
|
||||
}
|
||||
includeSources: true,
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
var map = JSON.parse(result.map);
|
||||
@@ -175,8 +175,8 @@ describe("sourcemaps", function() {
|
||||
sourceMap: {
|
||||
content: "inline",
|
||||
includeSources: true,
|
||||
url: "inline"
|
||||
}
|
||||
url: "inline",
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code + "\n", read("test/input/issue-520/output.js"));
|
||||
@@ -185,7 +185,7 @@ describe("sourcemaps", function() {
|
||||
var result = UglifyJS.minify(read("test/input/issue-1323/sample.js"), {
|
||||
mangle: false,
|
||||
sourceMap: {
|
||||
content: "inline"
|
||||
content: "inline",
|
||||
},
|
||||
warnings: true,
|
||||
});
|
||||
@@ -206,7 +206,7 @@ describe("sourcemaps", function() {
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, [
|
||||
"var Foo=function(){console.log(3)},bar=(new Foo,function(o){return o});",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwiMSJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFdBQWdCQyxRQUFRQyxJQUFJLElDQWxDQyxLREEyQyxJQUFJSCxJQ0MvQyxTQUFjRyxHQUNWLE9BQU9BIn0=",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwiMSJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFdBQWdCQyxRQUFRQyxJQUFJLENBQUcsQ0FBRSxFQ0F2Q0MsS0RBMkMsSUFBSUgsSUNDL0MsU0FBY0csR0FDVixPQUFPQSxDQUNYIn0=",
|
||||
].join("\n"));
|
||||
assert.deepEqual(result.warnings, [ "WARN: inline source map not found: 1" ]);
|
||||
});
|
||||
@@ -239,8 +239,8 @@ describe("sourcemaps", function() {
|
||||
sourceMap: {
|
||||
content: "inline",
|
||||
includeSources: true,
|
||||
url: "inline"
|
||||
}
|
||||
url: "inline",
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code + "\n", read("test/input/issue-3294/output.js"));
|
||||
@@ -255,7 +255,7 @@ describe("sourcemaps", function() {
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, '(function(){console.log("hello")}).call(this);');
|
||||
assert.strictEqual(result.map, '{"version":3,"sources":["main.coffee"],"names":["console","log"],"mappings":"CAAA,WAAAA,QAAQC,IAAI"}');
|
||||
assert.strictEqual(result.map, '{"version":3,"sources":["main.coffee"],"names":["console","log"],"mappings":"CAAA,WAAAA,QAAQC,IAAI,OAAZ"}');
|
||||
});
|
||||
it("Should not overwrite existing sourcesContent", function() {
|
||||
var result = UglifyJS.minify({
|
||||
@@ -302,7 +302,7 @@ describe("sourcemaps", function() {
|
||||
if (result.error) throw result.error;
|
||||
var code = result.code;
|
||||
assert.strictEqual(code, "var a=function(n){return n};\n" +
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsiYSIsImZvbyJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBSUEsRUFBSSxTQUFTQyxHQUFPLE9BQU9BIn0=");
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsiYSIsImZvbyJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBSUEsRUFBSSxTQUFTQyxHQUFPLE9BQU9BLENBQUsifQ==");
|
||||
});
|
||||
it("Should not append source map to output js when sourceMapInline is not enabled", function() {
|
||||
var result = UglifyJS.minify('var a = function(foo) { return foo; };');
|
||||
|
||||
@@ -9,19 +9,22 @@ function beautify(ast) {
|
||||
var beautified = UglifyJS.minify(ast, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
module: ufuzz.module,
|
||||
output: {
|
||||
ast: true,
|
||||
beautify: true,
|
||||
braces: true,
|
||||
},
|
||||
});
|
||||
if (beautified.error) return beautified;
|
||||
return UglifyJS.minify(beautified.code, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
ast: true,
|
||||
},
|
||||
});
|
||||
if (!beautified.error) {
|
||||
var verify = UglifyJS.minify(beautified.code, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
module: ufuzz.module,
|
||||
});
|
||||
if (verify.error) return verify;
|
||||
}
|
||||
return beautified;
|
||||
}
|
||||
|
||||
function validate(ast) {
|
||||
@@ -35,6 +38,7 @@ function validate(ast) {
|
||||
return UglifyJS.minify(ast, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
module: ufuzz.module,
|
||||
output: {
|
||||
ast: true,
|
||||
},
|
||||
@@ -57,12 +61,12 @@ function test(input, to_moz, description, skip_on_error, beautified) {
|
||||
var ast = UglifyJS.AST_Node.from_mozilla_ast(to_moz(input));
|
||||
} catch (e) {
|
||||
if (skip_on_error) return true;
|
||||
console.log("//=============================================================");
|
||||
console.log("//", description, "failed... round", round);
|
||||
console.log(e);
|
||||
console.log("// original code");
|
||||
if (beautified === true) console.log("// (beautified)");
|
||||
console.log(input.code);
|
||||
console.error("//=============================================================");
|
||||
console.error("//", description, "failed... round", round);
|
||||
console.error(e);
|
||||
console.error("// original code");
|
||||
if (beautified === true) console.error("// (beautified)");
|
||||
console.error(input.code);
|
||||
return false;
|
||||
}
|
||||
var transformed = validate(ast);
|
||||
@@ -74,34 +78,34 @@ function test(input, to_moz, description, skip_on_error, beautified) {
|
||||
if (!test(beautified, to_moz, description, skip_on_error, true)) return false;
|
||||
}
|
||||
}
|
||||
console.log("//=============================================================");
|
||||
console.log("// !!!!!! Failed... round", round);
|
||||
console.log("// original code");
|
||||
console.error("//=============================================================");
|
||||
console.error("// !!!!!! Failed... round", round);
|
||||
console.error("// original code");
|
||||
if (beautified.error) {
|
||||
console.log("// !!! beautify failed !!!");
|
||||
console.log(beautified.error.stack);
|
||||
console.error("// !!! beautify failed !!!");
|
||||
console.error(beautified.error.stack);
|
||||
} else if (beautified === true) {
|
||||
console.log("// (beautified)");
|
||||
console.error("// (beautified)");
|
||||
}
|
||||
console.log(input.raw);
|
||||
console.log();
|
||||
console.log();
|
||||
console.log("//-------------------------------------------------------------");
|
||||
console.log("//", description);
|
||||
console.error(input.raw);
|
||||
console.error();
|
||||
console.error();
|
||||
console.error("//-------------------------------------------------------------");
|
||||
console.error("//", description);
|
||||
if (transformed.error) {
|
||||
console.log(transformed.error.stack);
|
||||
console.error(transformed.error.stack);
|
||||
} else {
|
||||
beautified = beautify(transformed.ast);
|
||||
if (beautified.error) {
|
||||
console.log("// !!! beautify failed !!!");
|
||||
console.log(beautified.error.stack);
|
||||
console.log(transformed.code);
|
||||
console.error("// !!! beautify failed !!!");
|
||||
console.error(beautified.error.stack);
|
||||
console.error(transformed.code);
|
||||
} else {
|
||||
console.log("// (beautified)");
|
||||
console.log(beautified.code);
|
||||
console.error("// (beautified)");
|
||||
console.error(beautified.code);
|
||||
}
|
||||
}
|
||||
console.log("!!!!!! Failed... round", round);
|
||||
console.error("!!!!!! Failed... round", round);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -115,9 +119,29 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
var code = ufuzz.createTopLevelCode();
|
||||
minify_options.forEach(function(options) {
|
||||
var ok = true;
|
||||
var input = UglifyJS.minify(options ? UglifyJS.minify(code, JSON.parse(options)).code : code, {
|
||||
var minified;
|
||||
if (options) {
|
||||
var o = JSON.parse(options);
|
||||
o.module = ufuzz.module;
|
||||
minified = UglifyJS.minify(code, o);
|
||||
if (minified.error) {
|
||||
console.log("//=============================================================");
|
||||
console.log("// minify() failed... round", round);
|
||||
console.log("// original code");
|
||||
console.log(code);
|
||||
console.log();
|
||||
console.log();
|
||||
console.log("//-------------------------------------------------------------");
|
||||
console.log("minify(options):");
|
||||
console.log(JSON.stringify(o, null, 2));
|
||||
return;
|
||||
}
|
||||
minified = minified.code;
|
||||
}
|
||||
var input = UglifyJS.minify(minified || code, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
module: ufuzz.module,
|
||||
output: {
|
||||
ast: true,
|
||||
},
|
||||
@@ -125,11 +149,27 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
input.raw = options ? input.code : code;
|
||||
if (input.error) {
|
||||
ok = false;
|
||||
console.log("//=============================================================");
|
||||
console.log("// minify() failed... round", round);
|
||||
console.log(input.error);
|
||||
console.log("// original code");
|
||||
console.log(code);
|
||||
console.error("//=============================================================");
|
||||
console.error("// parse() failed... round", round);
|
||||
console.error("// original code");
|
||||
console.error(code);
|
||||
console.error();
|
||||
console.error();
|
||||
if (options) {
|
||||
console.error("//-------------------------------------------------------------");
|
||||
console.error("// minified code");
|
||||
console.error(minified);
|
||||
console.error();
|
||||
console.error();
|
||||
console.error("//-------------------------------------------------------------");
|
||||
console.error("minify(options):");
|
||||
console.error(JSON.stringify(o, null, 2));
|
||||
console.error();
|
||||
console.error();
|
||||
}
|
||||
console.error("//-------------------------------------------------------------");
|
||||
console.error("// parse() error");
|
||||
console.error(input.error);
|
||||
}
|
||||
if (ok) ok = test(input, function(input) {
|
||||
return input.ast.to_mozilla_ast();
|
||||
@@ -141,7 +181,10 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
sourceType: "module",
|
||||
});
|
||||
}, "acorn.parse()", !ufuzz.verbose);
|
||||
if (!ok) process.exit(1);
|
||||
if (!ok && isFinite(num_iterations)) {
|
||||
console.log();
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
console.log();
|
||||
|
||||
@@ -160,6 +160,11 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
return expr instanceof U.AST_Spread ? expr.expression : expr;
|
||||
}
|
||||
}
|
||||
else if (node instanceof U.AST_Await) {
|
||||
node.start._permute++;
|
||||
CHANGED = true;
|
||||
return node.expression;
|
||||
}
|
||||
else if (node instanceof U.AST_Binary) {
|
||||
var permute = ((node.start._permute += step) * steps | 0) % 4;
|
||||
var expr = [
|
||||
@@ -241,23 +246,6 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
CHANGED = true;
|
||||
return node.name;
|
||||
}
|
||||
else if (node instanceof U.AST_DestructuredArray) {
|
||||
var expr = node.elements[0];
|
||||
if (expr && !(expr instanceof U.AST_Hole)) {
|
||||
node.start._permute++;
|
||||
CHANGED = true;
|
||||
return expr;
|
||||
}
|
||||
}
|
||||
else if (node instanceof U.AST_DestructuredObject) {
|
||||
// first property's value
|
||||
var expr = node.properties[0];
|
||||
if (expr) {
|
||||
node.start._permute++;
|
||||
CHANGED = true;
|
||||
return expr.value;
|
||||
}
|
||||
}
|
||||
else if (node instanceof U.AST_Defun) {
|
||||
switch (((node.start._permute += step) * steps | 0) % 2) {
|
||||
case 0:
|
||||
@@ -275,6 +263,23 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (node instanceof U.AST_DestructuredArray) {
|
||||
var expr = node.elements[0];
|
||||
if (expr && !(expr instanceof U.AST_Hole)) {
|
||||
node.start._permute++;
|
||||
CHANGED = true;
|
||||
return expr;
|
||||
}
|
||||
}
|
||||
else if (node instanceof U.AST_DestructuredObject) {
|
||||
// first property's value
|
||||
var expr = node.properties[0];
|
||||
if (expr) {
|
||||
node.start._permute++;
|
||||
CHANGED = true;
|
||||
return expr.value;
|
||||
}
|
||||
}
|
||||
else if (node instanceof U.AST_DWLoop) {
|
||||
var expr = [
|
||||
node.condition,
|
||||
@@ -296,6 +301,16 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
return to_statement(expr);
|
||||
}
|
||||
}
|
||||
else if (node instanceof U.AST_ExportDeclaration) {
|
||||
node.start._permute++;
|
||||
CHANGED = true;
|
||||
return node.body;
|
||||
}
|
||||
else if (node instanceof U.AST_ExportDefault) {
|
||||
node.start._permute++;
|
||||
CHANGED = true;
|
||||
return to_statement(node.body);
|
||||
}
|
||||
else if (node instanceof U.AST_Finally) {
|
||||
// drop finally block
|
||||
node.start._permute++;
|
||||
@@ -351,6 +366,15 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
return to_statement(expr);
|
||||
}
|
||||
}
|
||||
else if (node instanceof U.AST_LabeledStatement) {
|
||||
if (node.body instanceof U.AST_Statement
|
||||
&& !has_loopcontrol(node.body, node.body, node)) {
|
||||
// replace labelled statement with its non-labelled body
|
||||
node.start._permute = REPLACEMENTS.length;
|
||||
CHANGED = true;
|
||||
return node.body;
|
||||
}
|
||||
}
|
||||
else if (node instanceof U.AST_Object) {
|
||||
// first property's value
|
||||
var expr = node.properties[0];
|
||||
@@ -441,13 +465,14 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
return to_statement(node.definitions[0].value);
|
||||
}
|
||||
}
|
||||
else if (node instanceof U.AST_LabeledStatement) {
|
||||
if (node.body instanceof U.AST_Statement
|
||||
&& !has_loopcontrol(node.body, node.body, node)) {
|
||||
// replace labelled statement with its non-labelled body
|
||||
node.start._permute = REPLACEMENTS.length;
|
||||
else if (node instanceof U.AST_VarDef) {
|
||||
if (node.value && !(node.name instanceof U.AST_Destructured || parent instanceof U.AST_Const)) {
|
||||
node.start._permute++;
|
||||
CHANGED = true;
|
||||
return node.body;
|
||||
return new U.AST_VarDef({
|
||||
name: node.name,
|
||||
start: {},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -760,9 +785,9 @@ function compare_run_code(code, minify_options, result_cache, max_timeout) {
|
||||
if (minified.error) return minified;
|
||||
|
||||
var toplevel = sandbox.has_toplevel(minify_options);
|
||||
var unminified = run_code(code, toplevel, result_cache, max_timeout);
|
||||
var unminified = run(code, max_timeout);
|
||||
var timeout = Math.min(100 * unminified.elapsed, max_timeout);
|
||||
var minified_result = run_code(minified.code, toplevel, result_cache, timeout).result;
|
||||
var minified_result = run(minified.code, timeout).result;
|
||||
|
||||
if (sandbox.same_stdout(unminified.result, minified_result)) {
|
||||
return is_timed_out(unminified.result) && is_timed_out(minified_result) && {
|
||||
@@ -774,6 +799,16 @@ function compare_run_code(code, minify_options, result_cache, max_timeout) {
|
||||
minified_result: minified_result,
|
||||
elapsed: unminified.elapsed,
|
||||
};
|
||||
|
||||
function run(code, timeout) {
|
||||
if (minify_options.module) code = [
|
||||
'"use strict";',
|
||||
"(async()=>{",
|
||||
code,
|
||||
'})().catch(e=>process.on("exit",()=>{throw e}));',
|
||||
].join("\n");
|
||||
return run_code(code, toplevel, result_cache, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
function test_minify(code, minify_options) {
|
||||
|
||||
@@ -36,7 +36,7 @@ EOF
|
||||
}
|
||||
if [ $NATIVE ]; then unset -f timeout; fi
|
||||
|
||||
while !(git clone --branch v1.6.0 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs); do
|
||||
while !(git clone --branch v1.6.2 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs); do
|
||||
rm -rf ~/.nvs
|
||||
done
|
||||
while ! timeout 60 bash -c ". ~/.nvs/nvs.sh add $NODE && nvs use $NODE"; do
|
||||
@@ -48,6 +48,8 @@ done
|
||||
nvs use $NODE
|
||||
node --version
|
||||
npm config set audit false
|
||||
npm config set fund false
|
||||
npm config set loglevel error
|
||||
npm config set optional false
|
||||
npm config set save false
|
||||
npm config set strict-ssl false
|
||||
|
||||
@@ -57,7 +57,7 @@ exports.patch_module_statements = function(code) {
|
||||
strict_mode = match;
|
||||
return "";
|
||||
}).replace(/\bexport(?:\s*\{[^{}]*}\s*?(?:$|\n|;)|\s+default\b(?:\s*(\(|\{|class\s*\{|class\s+(?=extends\b)|(?:async\s+)?function\s*(?:\*\s*)?\())?|\b)/g, function(match, header) {
|
||||
if (/^export\s+default/.test(match)) has_default = "var _uglify_export_default_;";
|
||||
if (/^export\s+default/.test(match)) has_default = "function _uglify_export_default_() {}";
|
||||
if (!header) return "";
|
||||
if (header.length == 1) return "0, " + header;
|
||||
var name = "_uglify_export_default_";
|
||||
|
||||
@@ -2,15 +2,18 @@ var get = require("https").get;
|
||||
var parse = require("url").parse;
|
||||
|
||||
var base, token, run_number;
|
||||
var expires = Date.now() + (6 * 60 - 10) * 60 * 1000;
|
||||
exports.init = function(url, auth, num) {
|
||||
base = url;
|
||||
token = auth;
|
||||
run_number = num;
|
||||
};
|
||||
exports.should_stop = function(callback) {
|
||||
if (Date.now() > expires) return callback();
|
||||
read(base + "/actions/runs?per_page=100", function(reply) {
|
||||
if (!reply || !Array.isArray(reply.workflow_runs)) return;
|
||||
var runs = reply.workflow_runs.sort(function(a, b) {
|
||||
var runs = verify(reply, "workflow_runs").filter(function(workflow) {
|
||||
return workflow.status != "completed";
|
||||
}).sort(function(a, b) {
|
||||
return b.run_number - a.run_number;
|
||||
});
|
||||
var found = false, remaining = 20;
|
||||
@@ -19,15 +22,13 @@ exports.should_stop = function(callback) {
|
||||
do {
|
||||
workflow = runs.pop();
|
||||
if (!workflow) return;
|
||||
if (is_cron(workflow) && workflow.run_number == run_number) found = true;
|
||||
} while (!found && workflow.status == "completed");
|
||||
if (!is_cron(workflow)) break;
|
||||
if (workflow.run_number == run_number) found = true;
|
||||
} while (!found);
|
||||
read(workflow.jobs_url, function(reply) {
|
||||
if (!reply || !Array.isArray(reply.jobs)) return;
|
||||
if (!reply.jobs.every(function(job) {
|
||||
if (job.status == "completed") return true;
|
||||
remaining--;
|
||||
return found || !is_cron(workflow);
|
||||
})) return;
|
||||
verify(reply, "jobs").forEach(function(job) {
|
||||
if (job.status != "completed") remaining--;
|
||||
});
|
||||
if (remaining >= 0) {
|
||||
next();
|
||||
} else {
|
||||
@@ -70,3 +71,12 @@ function read(url, callback) {
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
function verify(reply, field) {
|
||||
if (!reply) return [];
|
||||
var values = reply[field];
|
||||
if (!Array.isArray(values)) return [];
|
||||
return values.filter(function(value) {
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -140,6 +140,7 @@ var SUPPORT = function(matrix) {
|
||||
class: "class C { f() {} }",
|
||||
class_field: "class C { p = 0; }",
|
||||
class_private: "class C { #f() {} }",
|
||||
class_static_init: "class C { static {} }",
|
||||
computed_key: "({[0]: 0});",
|
||||
const_block: "var a; { const a = 0; }",
|
||||
default_value: "[ a = 0 ] = [];",
|
||||
@@ -252,7 +253,7 @@ BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||
if (SUPPORT.exponentiation) BINARY_OPS.push("**");
|
||||
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||
BINARY_OPS.push(" in ");
|
||||
BINARY_OPS.push(" in ", " instanceof ");
|
||||
|
||||
var ASSIGNMENTS = [ "=" ];
|
||||
ASSIGNMENTS = ASSIGNMENTS.concat(ASSIGNMENTS);
|
||||
@@ -370,9 +371,16 @@ var in_class = 0;
|
||||
var called = Object.create(null);
|
||||
var labels = 10000;
|
||||
|
||||
function rng(max) {
|
||||
function rng(limit) {
|
||||
var r = randomBytes(2).readUInt16LE(0) / 65536;
|
||||
return Math.floor(max * r);
|
||||
return Math.floor(limit * r);
|
||||
}
|
||||
|
||||
function get_num(max) {
|
||||
if (rng(max + 1) == 0) return 0;
|
||||
var i = 1;
|
||||
while (i < max && rng(2)) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
function strictMode() {
|
||||
@@ -405,7 +413,7 @@ function createTopLevelCode() {
|
||||
unique_vars.length = 0;
|
||||
classes.length = 0;
|
||||
allow_this = true;
|
||||
async = false;
|
||||
async = SUPPORT.async && rng(200) == 0;
|
||||
has_await = false;
|
||||
export_default = false;
|
||||
generator = false;
|
||||
@@ -413,7 +421,7 @@ function createTopLevelCode() {
|
||||
funcs = 0;
|
||||
clazz = 0;
|
||||
imports = 0;
|
||||
in_class = 0;
|
||||
in_class = async;
|
||||
called = Object.create(null);
|
||||
var s = [
|
||||
strictMode(),
|
||||
@@ -424,7 +432,7 @@ function createTopLevelCode() {
|
||||
if (rng(2)) {
|
||||
s.push(createStatements(3, MAX_GENERATION_RECURSION_DEPTH, CANNOT_THROW, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, 0));
|
||||
} else {
|
||||
s.push(createFunctions(rng(MAX_GENERATED_TOPLEVELS_PER_RUN) + 1, MAX_GENERATION_RECURSION_DEPTH, DEFUN_OK, CANNOT_THROW, 0));
|
||||
s.push(createFunctions(MAX_GENERATED_TOPLEVELS_PER_RUN, MAX_GENERATION_RECURSION_DEPTH, DEFUN_OK, CANNOT_THROW, 0));
|
||||
}
|
||||
});
|
||||
// preceding `null` makes for a cleaner output (empty string still shows up etc)
|
||||
@@ -437,7 +445,7 @@ function createTopLevelCode() {
|
||||
function createFunctions(n, recurmax, allowDefun, canThrow, stmtDepth) {
|
||||
if (--recurmax < 0) { return ";"; }
|
||||
var s = "";
|
||||
while (n-- > 0) {
|
||||
for (var i = get_num(n - 1) + 1; --i >= 0;) {
|
||||
s += createFunction(recurmax, allowDefun, canThrow, stmtDepth) + "\n";
|
||||
}
|
||||
return s;
|
||||
@@ -454,7 +462,7 @@ function createParams(was_async, was_generator, noDuplicate) {
|
||||
if (!generator) generator = was_generator;
|
||||
var len = unique_vars.length;
|
||||
var params = [];
|
||||
for (var n = rng(4); --n >= 0;) {
|
||||
for (var i = get_num(3); --i >= 0;) {
|
||||
var name = createVarName(MANDATORY);
|
||||
if (noDuplicate || in_class) unique_vars.push(name);
|
||||
params.push(name);
|
||||
@@ -469,7 +477,7 @@ function createArgs(recurmax, stmtDepth, canThrow, noTemplate) {
|
||||
recurmax--;
|
||||
if (SUPPORT.template && !noTemplate && rng(20) == 0) return createTemplateLiteral(recurmax, stmtDepth, canThrow);
|
||||
var args = [];
|
||||
for (var n = rng(4); --n >= 0;) switch (SUPPORT.spread ? rng(50) : 3) {
|
||||
for (var i = get_num(3); --i >= 0;) switch (SUPPORT.spread ? rng(50) : 3) {
|
||||
case 0:
|
||||
case 1:
|
||||
var name = getVarName();
|
||||
@@ -849,7 +857,7 @@ function createFunction(recurmax, allowDefun, canThrow, stmtDepth) {
|
||||
s.push(defns());
|
||||
if (rng(5) === 0) {
|
||||
// functions with functions. lower the recursion to prevent a mess.
|
||||
s.push(createFunctions(rng(5) + 1, Math.ceil(recurmax * 0.7), DEFUN_OK, canThrow, stmtDepth));
|
||||
s.push(createFunctions(5, Math.ceil(recurmax * 0.7), DEFUN_OK, canThrow, stmtDepth));
|
||||
} else {
|
||||
// functions with statements
|
||||
s.push(_createStatements(3, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth));
|
||||
@@ -879,9 +887,9 @@ function createFunction(recurmax, allowDefun, canThrow, stmtDepth) {
|
||||
}
|
||||
|
||||
function _createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) {
|
||||
if (--recurmax < 0) { return ";"; }
|
||||
if (--recurmax < 0) return ";";
|
||||
var s = "";
|
||||
while (--n > 0) {
|
||||
for (var i = get_num(n); --i >= 0;) {
|
||||
s += createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "\n";
|
||||
}
|
||||
return s;
|
||||
@@ -962,7 +970,7 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
||||
switch (target) {
|
||||
case STMT_BLOCK:
|
||||
var label = createLabel(canBreak);
|
||||
return label.target + "{" + createStatements(rng(5) + 1, recurmax, canThrow, label.break, canContinue, cannotReturn, stmtDepth) + "}";
|
||||
return label.target + "{" + createStatements(5, recurmax, canThrow, label.break, canContinue, cannotReturn, stmtDepth) + "}";
|
||||
case STMT_IF_ELSE:
|
||||
return "if (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ")" + createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + (rng(2) ? " else " + createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) : "");
|
||||
case STMT_DO_WHILE:
|
||||
@@ -1075,7 +1083,7 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
||||
s += " * as " + createImportAlias();
|
||||
} else {
|
||||
var names = [];
|
||||
for (var i = rng(4); --i >= 0;) {
|
||||
for (var i = get_num(3); --i >= 0;) {
|
||||
var name = createImportAlias();
|
||||
names.push(rng(2) ? getDotKey() + " as " + name : name);
|
||||
}
|
||||
@@ -1181,7 +1189,11 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
||||
unique_vars.length = unique_len;
|
||||
});
|
||||
}
|
||||
if (n !== 0) s += " finally { " + createStatements(3, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + " }";
|
||||
if (n !== 0) s += [
|
||||
" finally { ",
|
||||
createStatements(5, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
||||
" }",
|
||||
].join("");
|
||||
return s;
|
||||
case STMT_C:
|
||||
return "c = c + 1;";
|
||||
@@ -1199,7 +1211,7 @@ function createSwitchParts(recurmax, n, canThrow, canBreak, canContinue, cannotR
|
||||
if (hadDefault || rng(5) > 0) {
|
||||
s.push(
|
||||
"case " + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + ":",
|
||||
_createStatements(rng(3) + 1, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
||||
_createStatements(3, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
||||
rng(10) > 0 ? " break;" : "/* fall-through */",
|
||||
""
|
||||
);
|
||||
@@ -1207,7 +1219,7 @@ function createSwitchParts(recurmax, n, canThrow, canBreak, canContinue, cannotR
|
||||
hadDefault = true;
|
||||
s.push(
|
||||
"default:",
|
||||
_createStatements(rng(3) + 1, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
||||
_createStatements(3, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
||||
""
|
||||
);
|
||||
}
|
||||
@@ -1338,7 +1350,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
"(" + params + "{",
|
||||
strictMode(),
|
||||
defns(),
|
||||
_createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth)
|
||||
_createStatements(5, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth)
|
||||
);
|
||||
suffix = "})";
|
||||
} else {
|
||||
@@ -1370,7 +1382,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
s.push(
|
||||
"(" + makeFunction(name) + "(){",
|
||||
strictMode(),
|
||||
createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||
createStatements(5, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||
rng(2) ? "})" : "})()" + invokeGenerator(save_generator)
|
||||
);
|
||||
}
|
||||
@@ -1379,7 +1391,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
s.push(
|
||||
"+" + makeFunction(name) + "(){",
|
||||
strictMode(),
|
||||
createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||
createStatements(5, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||
"}()" + invokeGenerator(save_generator)
|
||||
);
|
||||
break;
|
||||
@@ -1387,7 +1399,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
s.push(
|
||||
"!" + makeFunction(name) + "(){",
|
||||
strictMode(),
|
||||
createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||
createStatements(5, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||
"}()" + invokeGenerator(save_generator)
|
||||
);
|
||||
break;
|
||||
@@ -1395,7 +1407,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
s.push(
|
||||
"void " + makeFunction(name) + "(){",
|
||||
strictMode(),
|
||||
createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||
createStatements(5, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||
"}()" + invokeGenerator(save_generator)
|
||||
);
|
||||
break;
|
||||
@@ -1411,10 +1423,10 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
var add_new_target = SUPPORT.new_target && VALUES.indexOf("new.target") < 0;
|
||||
if (add_new_target) VALUES.push("new.target");
|
||||
s.push(defns());
|
||||
if (instantiate) for (var i = rng(4); --i >= 0;) {
|
||||
if (instantiate) for (var i = get_num(3); --i >= 0;) {
|
||||
s.push((in_class ? "if (this) " : "") + createThisAssignment(recurmax, stmtDepth, canThrow));
|
||||
}
|
||||
s.push(_createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth));
|
||||
s.push(_createStatements(5, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth));
|
||||
if (add_new_target) VALUES.splice(VALUES.indexOf("new.target"), 1);
|
||||
});
|
||||
generator = save_generator;
|
||||
@@ -1560,7 +1572,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
function createArrayLiteral(recurmax, stmtDepth, canThrow) {
|
||||
recurmax--;
|
||||
var arr = [];
|
||||
for (var i = rng(6); --i >= 0;) switch (SUPPORT.spread ? rng(50) : 3 + rng(47)) {
|
||||
for (var i = get_num(5); --i >= 0;) switch (SUPPORT.spread ? rng(50) : 3 + rng(47)) {
|
||||
case 0:
|
||||
case 1:
|
||||
var name = getVarName();
|
||||
@@ -1589,7 +1601,7 @@ function createTemplateLiteral(recurmax, stmtDepth, canThrow) {
|
||||
recurmax--;
|
||||
var s = [];
|
||||
addText();
|
||||
for (var i = rng(6); --i >= 0;) {
|
||||
for (var i = get_num(5); --i >= 0;) {
|
||||
s.push("${", createExpression(recurmax, COMMA_OK, stmtDepth, canThrow), "}");
|
||||
addText();
|
||||
}
|
||||
@@ -1744,7 +1756,7 @@ function createObjectFunction(recurmax, stmtDepth, canThrow, internal, isClazz)
|
||||
s.push(_createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, stmtDepth));
|
||||
if (internal == "super") s.push("super" + createArgs(recurmax, stmtDepth, canThrow, NO_TEMPLATE) + ";");
|
||||
allow_this = save_allow;
|
||||
if (/^(constructor|super)$/.test(internal) || rng(10) == 0) for (var i = rng(4); --i >= 0;) {
|
||||
if (/^(constructor|super)$/.test(internal) || rng(10) == 0) for (var i = get_num(3); --i >= 0;) {
|
||||
s.push(rng(2) ? createSuperAssignment(recurmax, stmtDepth, canThrow) : createThisAssignment(recurmax, stmtDepth, canThrow));
|
||||
}
|
||||
s.push(_createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth), "}");
|
||||
@@ -1763,7 +1775,7 @@ function createObjectLiteral(recurmax, stmtDepth, canThrow) {
|
||||
var obj = [ "({" ];
|
||||
var offset = SUPPORT.spread_object ? 0 : SUPPORT.computed_key ? 2 : 4;
|
||||
var has_proto = false;
|
||||
for (var i = rng(6); --i >= 0;) switch (offset + rng(50 - offset)) {
|
||||
for (var i = get_num(5); --i >= 0;) switch (offset + rng(50 - offset)) {
|
||||
case 0:
|
||||
obj.push("..." + getVarName() + ",");
|
||||
break;
|
||||
@@ -1810,7 +1822,7 @@ function createClassLiteral(recurmax, stmtDepth, canThrow, name) {
|
||||
}
|
||||
s += " {\n";
|
||||
var declared = [];
|
||||
for (var i = rng(6); --i >= 0;) {
|
||||
for (var i = get_num(5); --i >= 0;) {
|
||||
var fixed = false;
|
||||
if (rng(5) == 0) {
|
||||
fixed = true;
|
||||
@@ -1839,6 +1851,16 @@ function createClassLiteral(recurmax, stmtDepth, canThrow, name) {
|
||||
async = save_async;
|
||||
}
|
||||
s += ";\n";
|
||||
} else if (SUPPORT.class_static_init && fixed && !internal && rng(10) == 0) {
|
||||
async = false;
|
||||
generator = false;
|
||||
s += [
|
||||
"{ ",
|
||||
createStatements(5, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, stmtDepth),
|
||||
" }\n",
|
||||
].join("");
|
||||
generator = save_generator;
|
||||
async = save_async;
|
||||
} else {
|
||||
if (!fixed && !internal && constructor && rng(10) == 0) {
|
||||
internal = constructor;
|
||||
@@ -1994,7 +2016,7 @@ function createBinaryOp(noComma, canThrow) {
|
||||
var op;
|
||||
do {
|
||||
op = BINARY_OPS[rng(BINARY_OPS.length)];
|
||||
} while (noComma && op == "," || !canThrow && op == " in ");
|
||||
} while (noComma && op == "," || !canThrow && /^ in/.test(op));
|
||||
return op;
|
||||
}
|
||||
|
||||
@@ -2080,13 +2102,23 @@ function createVarName(maybe, dontStore) {
|
||||
}
|
||||
|
||||
if (require.main !== module) {
|
||||
exports.createTopLevelCode = createTopLevelCode;
|
||||
exports.createTopLevelCode = function() {
|
||||
var code = createTopLevelCode();
|
||||
exports.module = async && has_await;
|
||||
return code;
|
||||
};
|
||||
exports.num_iterations = num_iterations;
|
||||
exports.verbose = verbose;
|
||||
return;
|
||||
}
|
||||
|
||||
function run_code(code, toplevel, timeout) {
|
||||
if (async && has_await) code = [
|
||||
'"use strict";',
|
||||
"(async()=>{",
|
||||
code,
|
||||
'})().catch(e=>process.on("exit",()=>{throw e}));',
|
||||
].join("\n");
|
||||
return sandbox.run_code(sandbox.patch_module_statements(code), toplevel, timeout);
|
||||
}
|
||||
|
||||
@@ -2106,7 +2138,9 @@ function errorln(msg) {
|
||||
}
|
||||
|
||||
function try_beautify(code, toplevel, result, printfn, options) {
|
||||
var beautified = UglifyJS.minify(code, JSON.parse(beautify_options));
|
||||
var o = JSON.parse(beautify_options);
|
||||
if (async && has_await) o.module = true;
|
||||
var beautified = UglifyJS.minify(code, o);
|
||||
if (beautified.error) {
|
||||
printfn("// !!! beautify failed !!!");
|
||||
printfn(beautified.error);
|
||||
@@ -2259,12 +2293,27 @@ function log(options) {
|
||||
}
|
||||
|
||||
function sort_globals(code) {
|
||||
var globals = run_code("throw Object.keys(this).sort(" + function(global) {
|
||||
var injected = "throw Object.keys(this).sort(" + function(global) {
|
||||
return function(m, n) {
|
||||
return (typeof global[n] == "function") - (typeof global[m] == "function")
|
||||
|| (m < n ? -1 : m > n ? 1 : 0);
|
||||
};
|
||||
} + "(this));\n" + code);
|
||||
} + "(this));";
|
||||
var save_async = async;
|
||||
if (async && has_await) {
|
||||
async = false;
|
||||
injected = [
|
||||
'"use strict";',
|
||||
injected,
|
||||
"(async function(){",
|
||||
code,
|
||||
"})();"
|
||||
].join("\n");
|
||||
} else {
|
||||
injected += "\n" + code;
|
||||
}
|
||||
var globals = run_code(injected);
|
||||
async = save_async;
|
||||
if (!Array.isArray(globals)) {
|
||||
errorln();
|
||||
errorln();
|
||||
@@ -2466,6 +2515,9 @@ var bug_class_static_await = SUPPORT.async && SUPPORT.class_field && sandbox.is_
|
||||
var bug_class_static_nontrivial = SUPPORT.class_field && sandbox.is_error(sandbox.run_code("class A { static 42; static get 42() {} }"));
|
||||
var bug_for_of_async = SUPPORT.for_await_of && sandbox.is_error(sandbox.run_code("var async; for (async of []);"));
|
||||
var bug_for_of_var = SUPPORT.for_of && SUPPORT.let && sandbox.is_error(sandbox.run_code("try {} catch (e) { for (var e of []); }"));
|
||||
var bug_proto_stream = function(ex) {
|
||||
return ex.name == "TypeError" && ex.message == "callback is not a function";
|
||||
}
|
||||
if (SUPPORT.destructuring && sandbox.is_error(sandbox.run_code("console.log([ 1 ], {} = 2);"))) {
|
||||
beautify_options.output.v8 = true;
|
||||
minify_options.forEach(function(o) {
|
||||
@@ -2496,11 +2548,17 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
println();
|
||||
// ignore v8 parser bug
|
||||
return bug_async_arrow_rest(result)
|
||||
// ignore Node.js `__proto__` quirks
|
||||
|| bug_proto_stream(result)
|
||||
// ignore runtime platform bugs
|
||||
|| result.message == "Script execution aborted.";
|
||||
})) continue;
|
||||
minify_options.forEach(function(options) {
|
||||
var o = JSON.parse(options);
|
||||
if (async && has_await) {
|
||||
o.module = true;
|
||||
options = JSON.stringify(o);
|
||||
}
|
||||
var toplevel = sandbox.has_toplevel(o);
|
||||
o.validate = true;
|
||||
uglify_code = UglifyJS.minify(original_code, o);
|
||||
@@ -2513,6 +2571,8 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
var uglify_erred = sandbox.is_error(uglify_result);
|
||||
// ignore v8 parser bug
|
||||
if (!ok && uglify_erred && bug_async_arrow_rest(uglify_result)) ok = true;
|
||||
// ignore Node.js `__proto__` quirks
|
||||
if (!ok && uglify_erred && bug_proto_stream(uglify_result)) ok = true;
|
||||
// ignore runtime platform bugs
|
||||
if (!ok && uglify_erred && uglify_result.message == "Script execution aborted.") ok = true;
|
||||
// handle difference caused by time-outs
|
||||
|
||||
Reference in New Issue
Block a user