Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -50,7 +50,7 @@ jobs:
|
|||||||
OPTIONS: ${{ matrix.options }}
|
OPTIONS: ${{ matrix.options }}
|
||||||
SCRIPT: ${{ matrix.script }}
|
SCRIPT: ${{ matrix.script }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Perform uglify, build & test
|
- name: Perform uglify, build & test
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
5
.github/workflows/ci.yml
vendored
5
.github/workflows/ci.yml
vendored
@@ -15,9 +15,10 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
NODE: ${{ matrix.node }}
|
NODE: ${{ matrix.node }}
|
||||||
TYPE: ${{ matrix.script }}
|
TYPE: ${{ matrix.script }}
|
||||||
|
UGLIFY_GITHUB_LAG: 10000
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/cache@v2
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: tmp
|
path: tmp
|
||||||
key: tmp ${{ matrix.script }}
|
key: tmp ${{ matrix.script }}
|
||||||
|
|||||||
2
.github/workflows/ufuzz.yml
vendored
2
.github/workflows/ufuzz.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
NODE: ${{ matrix.node }}
|
NODE: ${{ matrix.node }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Perform fuzzing
|
- name: Perform fuzzing
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
20
README.md
20
README.md
@@ -54,8 +54,6 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
modules and Userscripts that may
|
modules and Userscripts that may
|
||||||
be anonymous function wrapped (IIFE)
|
be anonymous function wrapped (IIFE)
|
||||||
by the .user.js engine `caller`.
|
by the .user.js engine `caller`.
|
||||||
`expression` Parse a single expression, rather than
|
|
||||||
a program (for parsing JSON).
|
|
||||||
`spidermonkey` Assume input files are SpiderMonkey
|
`spidermonkey` Assume input files are SpiderMonkey
|
||||||
AST format (as JSON).
|
AST format (as JSON).
|
||||||
-c, --compress [options] Enable compressor/specify compressor options:
|
-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.
|
-d, --define <expr>[=value] Global definitions.
|
||||||
-e, --enclose [arg[:value]] Embed everything in a big function, with configurable
|
-e, --enclose [arg[:value]] Embed everything in a big function, with configurable
|
||||||
argument(s) & value(s).
|
argument(s) & value(s).
|
||||||
|
--expression Parse a single expression, rather than a program
|
||||||
|
(for parsing JSON).
|
||||||
--ie Support non-standard Internet Explorer.
|
--ie Support non-standard Internet Explorer.
|
||||||
Equivalent to setting `ie: true` in `minify()`
|
Equivalent to setting `ie: true` in `minify()`
|
||||||
for `compress`, `mangle` and `output` options.
|
for `compress`, `mangle` and `output` options.
|
||||||
@@ -504,6 +504,8 @@ if (result.error) throw result.error;
|
|||||||
- `compress` (default: `{}`) — pass `false` to skip compressing entirely.
|
- `compress` (default: `{}`) — pass `false` to skip compressing entirely.
|
||||||
Pass an object to specify custom [compress options](#compress-options).
|
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.
|
- `ie` (default: `false`) — enable workarounds for Internet Explorer bugs.
|
||||||
|
|
||||||
- `keep_fargs` (default: `false`) — pass `true` to prevent discarding or mangling
|
- `keep_fargs` (default: `false`) — pass `true` to prevent discarding or mangling
|
||||||
@@ -633,8 +635,6 @@ to be `false` and all symbol names will be omitted.
|
|||||||
|
|
||||||
- `bare_returns` (default: `false`) — support top level `return` statements
|
- `bare_returns` (default: `false`) — support top level `return` statements
|
||||||
|
|
||||||
- `expression` (default: `false`) — parse as a single expression, e.g. JSON
|
|
||||||
|
|
||||||
- `html5_comments` (default: `true`) — process HTML comment as workaround for
|
- `html5_comments` (default: `true`) — process HTML comment as workaround for
|
||||||
browsers which do not recognise `<script>` tags
|
browsers which do not recognise `<script>` tags
|
||||||
|
|
||||||
@@ -1359,7 +1359,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'.
|
// 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.
|
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:
|
following:
|
||||||
```javascript
|
```javascript
|
||||||
console.log({
|
console.log({
|
||||||
@@ -1368,9 +1368,15 @@ To allow for better optimizations, the compiler makes various assumptions:
|
|||||||
return "FAIL";
|
return "FAIL";
|
||||||
},
|
},
|
||||||
[42]: "PASS",
|
[42]: "PASS",
|
||||||
|
}[42], {
|
||||||
|
...console,
|
||||||
|
get 42() {
|
||||||
|
return "FAIL";
|
||||||
|
},
|
||||||
|
42: "PASS",
|
||||||
}[42]);
|
}[42]);
|
||||||
// Expected: "PASS"
|
// Expected: "PASS PASS"
|
||||||
// Actual: "FAIL"
|
// Actual: "PASS FAIL"
|
||||||
```
|
```
|
||||||
UglifyJS may modify the input which in turn may suppress those errors.
|
UglifyJS may modify the input which in turn may suppress those errors.
|
||||||
- Earlier versions of JavaScript will throw `TypeError` with the following:
|
- Earlier versions of JavaScript will throw `TypeError` with the following:
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ function process_option(name, no_value) {
|
|||||||
" --config-file <file> Read minify() options from JSON file.",
|
" --config-file <file> Read minify() options from JSON file.",
|
||||||
" -d, --define <expr>[=value] Global definitions.",
|
" -d, --define <expr>[=value] Global definitions.",
|
||||||
" -e, --enclose [arg[,...][:value[,...]]] Embed everything in a big function, with configurable argument(s) & value(s).",
|
" -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.",
|
" --ie Support non-standard Internet Explorer.",
|
||||||
" --keep-fargs Do not mangle/drop function arguments.",
|
" --keep-fargs Do not mangle/drop function arguments.",
|
||||||
" --keep-fnames Do not mangle/drop function names. Useful for code relying on Function.prototype.name.",
|
" --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();
|
options[name] = read_value();
|
||||||
break;
|
break;
|
||||||
case "annotations":
|
case "annotations":
|
||||||
|
case "expression":
|
||||||
case "ie":
|
case "ie":
|
||||||
case "ie8":
|
case "ie8":
|
||||||
case "module":
|
case "module":
|
||||||
|
|||||||
274
lib/ast.js
274
lib/ast.js
@@ -109,6 +109,9 @@ var AST_Node = DEFNODE("Node", "start end", {
|
|||||||
start: "[AST_Token] The first token of this node",
|
start: "[AST_Token] The first token of this node",
|
||||||
end: "[AST_Token] The last 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) {
|
walk: function(visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
},
|
},
|
||||||
@@ -125,12 +128,7 @@ var AST_Node = DEFNODE("Node", "start end", {
|
|||||||
var marker = {};
|
var marker = {};
|
||||||
this.walk(new TreeWalker(function(node) {
|
this.walk(new TreeWalker(function(node) {
|
||||||
if (node.validate_visited === marker) {
|
if (node.validate_visited === marker) {
|
||||||
throw new Error(string_template("cannot reuse {type} from [{file}:{line},{col}]", {
|
throw new Error(string_template("cannot reuse AST_{TYPE} from [{start}]", node));
|
||||||
type: "AST_" + node.TYPE,
|
|
||||||
file: node.start.file,
|
|
||||||
line: node.start.line,
|
|
||||||
col: node.start.col,
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
node.validate_visited = marker;
|
node.validate_visited = marker;
|
||||||
}));
|
}));
|
||||||
@@ -138,6 +136,7 @@ var AST_Node = DEFNODE("Node", "start end", {
|
|||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
DEF_BITPROPS(AST_Node, [
|
DEF_BITPROPS(AST_Node, [
|
||||||
|
// AST_Node
|
||||||
"_optimized",
|
"_optimized",
|
||||||
"_squeezed",
|
"_squeezed",
|
||||||
// AST_Call
|
// AST_Call
|
||||||
@@ -172,6 +171,8 @@ DEF_BITPROPS(AST_Node, [
|
|||||||
"pure",
|
"pure",
|
||||||
// AST_Assign
|
// AST_Assign
|
||||||
"redundant",
|
"redundant",
|
||||||
|
// AST_Node
|
||||||
|
"single_use",
|
||||||
// AST_ClassProperty
|
// AST_ClassProperty
|
||||||
"static",
|
"static",
|
||||||
// AST_Call
|
// AST_Call
|
||||||
@@ -231,6 +232,24 @@ AST_Node.disable_validation = function() {
|
|||||||
while (restore = restore_transforms.pop()) restore();
|
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 ]----- */
|
/* -----[ statements ]----- */
|
||||||
|
|
||||||
var AST_Statement = DEFNODE("Statement", null, {
|
var AST_Statement = DEFNODE("Statement", null, {
|
||||||
@@ -242,6 +261,7 @@ var AST_Statement = DEFNODE("Statement", null, {
|
|||||||
|
|
||||||
var AST_Debugger = DEFNODE("Debugger", null, {
|
var AST_Debugger = DEFNODE("Debugger", null, {
|
||||||
$documentation: "Represents a debugger statement",
|
$documentation: "Represents a debugger statement",
|
||||||
|
_equals: return_true,
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
var AST_Directive = DEFNODE("Directive", "quote value", {
|
var AST_Directive = DEFNODE("Directive", "quote value", {
|
||||||
@@ -250,6 +270,9 @@ var AST_Directive = DEFNODE("Directive", "quote value", {
|
|||||||
quote: "[string?] the original quote character",
|
quote: "[string?] the original quote character",
|
||||||
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
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() {
|
_validate: function() {
|
||||||
if (this.quote != null) {
|
if (this.quote != null) {
|
||||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
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);
|
}, AST_Statement);
|
||||||
|
|
||||||
var AST_EmptyStatement = DEFNODE("EmptyStatement", null, {
|
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);
|
}, AST_Statement);
|
||||||
|
|
||||||
function is_statement(node) {
|
function is_statement(node) {
|
||||||
@@ -291,6 +315,9 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)",
|
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.body.equals(node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -342,6 +369,9 @@ var AST_Block = DEFNODE("Block", "body", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
body: "[AST_Statement*] an array of statements"
|
body: "[AST_Statement*] an array of statements"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return all_equals(this.body, node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -376,6 +406,10 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
label: "[AST_Label] a label definition"
|
label: "[AST_Label] a label definition"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.label.equals(node.label)
|
||||||
|
&& this.body.equals(node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -417,6 +451,10 @@ var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"
|
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() {
|
_validate: function() {
|
||||||
if (this.TYPE == "DWLoop") throw new Error("should not instantiate AST_DWLoop");
|
if (this.TYPE == "DWLoop") throw new Error("should not instantiate AST_DWLoop");
|
||||||
must_be_expression(this, "condition");
|
must_be_expression(this, "condition");
|
||||||
@@ -431,7 +469,7 @@ var AST_Do = DEFNODE("Do", null, {
|
|||||||
node.body.walk(visitor);
|
node.body.walk(visitor);
|
||||||
node.condition.walk(visitor);
|
node.condition.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}, AST_DWLoop);
|
}, AST_DWLoop);
|
||||||
|
|
||||||
var AST_While = DEFNODE("While", null, {
|
var AST_While = DEFNODE("While", null, {
|
||||||
@@ -442,7 +480,7 @@ var AST_While = DEFNODE("While", null, {
|
|||||||
node.condition.walk(visitor);
|
node.condition.walk(visitor);
|
||||||
node.body.walk(visitor);
|
node.body.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}, AST_DWLoop);
|
}, AST_DWLoop);
|
||||||
|
|
||||||
var AST_For = DEFNODE("For", "init condition step", {
|
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",
|
condition: "[AST_Node?] the `for` termination clause, or null if empty",
|
||||||
step: "[AST_Node?] the `for` update 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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -479,6 +523,11 @@ var AST_ForEnumeration = DEFNODE("ForEnumeration", "init object", {
|
|||||||
init: "[AST_Node] the assignment target during iteration",
|
init: "[AST_Node] the assignment target during iteration",
|
||||||
object: "[AST_Node] the object to iterate over"
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -519,6 +568,10 @@ var AST_With = DEFNODE("With", "expression", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "[AST_Node] the `with` expression"
|
expression: "[AST_Node] the `with` expression"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.expression.equals(node.expression)
|
||||||
|
&& this.body.equals(node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -621,6 +674,13 @@ var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest safe_ids uses_argu
|
|||||||
});
|
});
|
||||||
if (this.rest) this.rest.walk(tw);
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -831,6 +891,11 @@ var AST_Class = DEFNODE("Class", "extends name properties", {
|
|||||||
extends: "[AST_Node?] the super class, or null if not specified",
|
extends: "[AST_Node?] the super class, or null if not specified",
|
||||||
properties: "[AST_ClassProperty*] array of class properties",
|
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) {
|
resolve: function(def_class) {
|
||||||
return def_class ? this : this.parent_scope.resolve();
|
return def_class ? this : this.parent_scope.resolve();
|
||||||
},
|
},
|
||||||
@@ -883,6 +948,12 @@ var AST_ClassProperty = DEFNODE("ClassProperty", "key private static value", {
|
|||||||
static: "[boolean] whether this is a static 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)",
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -959,6 +1030,9 @@ var AST_Exit = DEFNODE("Exit", "value", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -989,6 +1063,9 @@ var AST_LoopControl = DEFNODE("LoopControl", "label", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
label: "[AST_LabelRef?] the label, or null if none",
|
label: "[AST_LabelRef?] the label, or null if none",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return prop_equals(this.label, node.label);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1019,6 +1096,11 @@ var AST_If = DEFNODE("If", "condition alternative", {
|
|||||||
condition: "[AST_Node] the `if` condition",
|
condition: "[AST_Node] the `if` condition",
|
||||||
alternative: "[AST_Statement?] the `else` part, or null if not present"
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1042,6 +1124,10 @@ var AST_Switch = DEFNODE("Switch", "expression", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "[AST_Node] the `switch` “discriminant”"
|
expression: "[AST_Node] the `switch` “discriminant”"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.expression.equals(node.expression)
|
||||||
|
&& all_equals(this.body, node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1073,6 +1159,10 @@ var AST_Case = DEFNODE("Case", "expression", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "[AST_Node] the `case` expression"
|
expression: "[AST_Node] the `case` expression"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.expression.equals(node.expression)
|
||||||
|
&& all_equals(this.body, node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1093,6 +1183,11 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
|
|||||||
bcatch: "[AST_Catch?] the catch block, or null if not present",
|
bcatch: "[AST_Catch?] the catch block, or null if not present",
|
||||||
bfinally: "[AST_Finally?] the finally 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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1116,6 +1211,10 @@ var AST_Catch = DEFNODE("Catch", "argname", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
argname: "[(AST_Destructured|AST_SymbolCatch)?] symbol for the exception, or null if not present",
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1141,6 +1240,9 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
definitions: "[AST_VarDef*] array of variable definitions"
|
definitions: "[AST_VarDef*] array of variable definitions"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return all_equals(this.definitions, node.definitions);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1197,6 +1299,10 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
|
|||||||
name: "[AST_Destructured|AST_SymbolVar] name of the variable",
|
name: "[AST_Destructured|AST_SymbolVar] name of the variable",
|
||||||
value: "[AST_Node?] initializer, or null of there's no initializer",
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1216,6 +1322,9 @@ var AST_ExportDeclaration = DEFNODE("ExportDeclaration", "body", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
body: "[AST_DefClass|AST_Definitions|AST_LambdaDefinition] the statement to export",
|
body: "[AST_DefClass|AST_Definitions|AST_LambdaDefinition] the statement to export",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.body.equals(node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1236,6 +1345,9 @@ var AST_ExportDefault = DEFNODE("ExportDefault", "body", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
body: "[AST_Node] the default export",
|
body: "[AST_Node] the default export",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.body.equals(node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1249,29 +1361,29 @@ var AST_ExportDefault = DEFNODE("ExportDefault", "body", {
|
|||||||
},
|
},
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path quote", {
|
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path", {
|
||||||
$documentation: "An `export ... from '...'` statement",
|
$documentation: "An `export ... from '...'` statement",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
aliases: "[string*] array of aliases to export",
|
aliases: "[AST_String*] array of aliases to export",
|
||||||
keys: "[string*] array of keys to import",
|
keys: "[AST_String*] array of keys to import",
|
||||||
path: "[string] the path to import module",
|
path: "[AST_String] the path to import module",
|
||||||
quote: "[string?] the original quote character",
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.path.equals(node.path)
|
||||||
|
&& all_equals(this.aliases, node.aliases)
|
||||||
|
&& all_equals(this.keys, node.keys);
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.aliases.length != this.keys.length) {
|
if (this.aliases.length != this.keys.length) {
|
||||||
throw new Error("aliases:key length mismatch: " + this.aliases.length + " != " + this.keys.length);
|
throw new Error("aliases:key length mismatch: " + this.aliases.length + " != " + this.keys.length);
|
||||||
}
|
}
|
||||||
this.aliases.forEach(function(name) {
|
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) {
|
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.path instanceof AST_String)) throw new Error("path must be AST_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);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
@@ -1280,6 +1392,9 @@ var AST_ExportReferences = DEFNODE("ExportReferences", "properties", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
properties: "[AST_SymbolExport*] array of aliases to export",
|
properties: "[AST_SymbolExport*] array of aliases to export",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return all_equals(this.properties, node.properties);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1295,14 +1410,20 @@ var AST_ExportReferences = DEFNODE("ExportReferences", "properties", {
|
|||||||
},
|
},
|
||||||
}, AST_Statement);
|
}, 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",
|
$documentation: "An `import` statement",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
all: "[AST_SymbolImport?] the imported namespace, or null if not specified",
|
all: "[AST_SymbolImport?] the imported namespace, or null if not specified",
|
||||||
default: "[AST_SymbolImport?] the alias for default `export`, 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",
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
@@ -1321,16 +1442,12 @@ var AST_Import = DEFNODE("Import", "all default path properties quote", {
|
|||||||
}
|
}
|
||||||
if (this.default != null) {
|
if (this.default != null) {
|
||||||
if (!(this.default instanceof AST_SymbolImport)) throw new Error("default must be AST_SymbolImport");
|
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 (this.properties != null) this.properties.forEach(function(node) {
|
||||||
if (!(node instanceof AST_SymbolImport)) throw new Error("properties must contain AST_SymbolImport");
|
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);
|
}, AST_Statement);
|
||||||
|
|
||||||
@@ -1340,6 +1457,10 @@ var AST_DefaultValue = DEFNODE("DefaultValue", "name value", {
|
|||||||
name: "[AST_Destructured|AST_SymbolDeclaration] name of the variable",
|
name: "[AST_Destructured|AST_SymbolDeclaration] name of the variable",
|
||||||
value: "[AST_Node] value to assign if variable is `undefined`",
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1367,6 +1488,11 @@ var AST_Call = DEFNODE("Call", "args expression optional pure terminal", {
|
|||||||
pure: "[boolean/S] marker for side-effect-free call expression",
|
pure: "[boolean/S] marker for side-effect-free call expression",
|
||||||
terminal: "[boolean] whether the chain has ended",
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1395,6 +1521,9 @@ var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
|||||||
$propdoc: {
|
$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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1422,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",
|
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",
|
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() {
|
get_property: function() {
|
||||||
var p = this.property;
|
var p = this.property;
|
||||||
if (p instanceof AST_Constant) return p.value;
|
if (p instanceof AST_Constant) return p.value;
|
||||||
@@ -1466,6 +1600,9 @@ var AST_Spread = DEFNODE("Spread", "expression", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "[AST_Node] expression to be expanded",
|
expression: "[AST_Node] expression to be expanded",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.expression.equals(node.expression);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1483,6 +1620,10 @@ var AST_Unary = DEFNODE("Unary", "operator expression", {
|
|||||||
operator: "[string] the operator",
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1511,6 +1652,11 @@ var AST_Binary = DEFNODE("Binary", "operator left right", {
|
|||||||
operator: "[string] the operator",
|
operator: "[string] the operator",
|
||||||
right: "[AST_Node] right-hand side expression"
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1532,6 +1678,11 @@ var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative",
|
|||||||
consequent: "[AST_Node]",
|
consequent: "[AST_Node]",
|
||||||
alternative: "[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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1573,6 +1724,9 @@ var AST_Await = DEFNODE("Await", "expression", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "[AST_Node] expression with Promise to resolve on",
|
expression: "[AST_Node] expression with Promise to resolve on",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.expression.equals(node.expression);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1590,6 +1744,10 @@ var AST_Yield = DEFNODE("Yield", "expression nested", {
|
|||||||
expression: "[AST_Node?] return value for iterator, or null if undefined",
|
expression: "[AST_Node?] return value for iterator, or null if undefined",
|
||||||
nested: "[boolean] whether to iterate over expression as generator",
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1612,6 +1770,9 @@ var AST_Array = DEFNODE("Array", "elements", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
elements: "[AST_Node*] array of elements"
|
elements: "[AST_Node*] array of elements"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return all_equals(this.elements, node.elements);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1654,6 +1815,10 @@ var AST_DestructuredArray = DEFNODE("DestructuredArray", "elements", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
elements: "[(AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef)*] array of elements",
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1671,6 +1836,10 @@ var AST_DestructuredKeyVal = DEFNODE("DestructuredKeyVal", "key value", {
|
|||||||
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
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",
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1692,6 +1861,10 @@ var AST_DestructuredObject = DEFNODE("DestructuredObject", "properties", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
properties: "[AST_DestructuredKeyVal*] array of properties",
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1713,6 +1886,9 @@ var AST_Object = DEFNODE("Object", "properties", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
properties: "[(AST_ObjectProperty|AST_Spread)*] array of properties"
|
properties: "[(AST_ObjectProperty|AST_Spread)*] array of properties"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return all_equals(this.properties, node.properties);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1736,6 +1912,10 @@ var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
|||||||
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
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.",
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1790,6 +1970,9 @@ var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
|
|||||||
scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
|
scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
|
||||||
thedef: "[SymbolDef/S] the definition of this symbol"
|
thedef: "[SymbolDef/S] the definition of this symbol"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.thedef ? this.thedef === node.thedef : this.name == node.name;
|
||||||
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.TYPE == "Symbol") throw new Error("should not instantiate AST_Symbol");
|
if (this.TYPE == "Symbol") throw new Error("should not instantiate AST_Symbol");
|
||||||
if (typeof this.name != "string") throw new Error("name must be string");
|
if (typeof this.name != "string") throw new Error("name must be string");
|
||||||
@@ -1807,10 +1990,14 @@ var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
|||||||
var AST_SymbolImport = DEFNODE("SymbolImport", "key", {
|
var AST_SymbolImport = DEFNODE("SymbolImport", "key", {
|
||||||
$documentation: "Symbol defined by an `import` statement",
|
$documentation: "Symbol defined by an `import` statement",
|
||||||
$propdoc: {
|
$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() {
|
_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);
|
}, AST_SymbolConst);
|
||||||
|
|
||||||
@@ -1864,10 +2051,14 @@ var AST_SymbolRef = DEFNODE("SymbolRef", "fixed in_arg redef", {
|
|||||||
var AST_SymbolExport = DEFNODE("SymbolExport", "alias", {
|
var AST_SymbolExport = DEFNODE("SymbolExport", "alias", {
|
||||||
$documentation: "Reference in an `export` statement",
|
$documentation: "Reference in an `export` statement",
|
||||||
$propdoc: {
|
$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() {
|
_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);
|
}, AST_SymbolRef);
|
||||||
|
|
||||||
@@ -1877,6 +2068,7 @@ var AST_LabelRef = DEFNODE("LabelRef", null, {
|
|||||||
|
|
||||||
var AST_ObjectIdentity = DEFNODE("ObjectIdentity", null, {
|
var AST_ObjectIdentity = DEFNODE("ObjectIdentity", null, {
|
||||||
$documentation: "Base class for `super` & `this`",
|
$documentation: "Base class for `super` & `this`",
|
||||||
|
_equals: return_true,
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.TYPE == "ObjectIdentity") throw new Error("should not instantiate AST_ObjectIdentity");
|
if (this.TYPE == "ObjectIdentity") throw new Error("should not instantiate AST_ObjectIdentity");
|
||||||
},
|
},
|
||||||
@@ -1911,7 +2103,12 @@ var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expressions: "[AST_Node*] the placeholder expressions",
|
expressions: "[AST_Node*] the placeholder expressions",
|
||||||
strings: "[string*] the raw text segments",
|
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) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
@@ -1936,6 +2133,9 @@ var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
|||||||
|
|
||||||
var AST_Constant = DEFNODE("Constant", null, {
|
var AST_Constant = DEFNODE("Constant", null, {
|
||||||
$documentation: "Base class for all constants",
|
$documentation: "Base class for all constants",
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.value === node.value;
|
||||||
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.TYPE == "Constant") throw new Error("should not instantiate AST_Constant");
|
if (this.TYPE == "Constant") throw new Error("should not instantiate AST_Constant");
|
||||||
},
|
},
|
||||||
@@ -1984,6 +2184,9 @@ var AST_RegExp = DEFNODE("RegExp", "value", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
value: "[RegExp] the actual regexp"
|
value: "[RegExp] the actual regexp"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return "" + this.value == "" + node.value;
|
||||||
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (!(this.value instanceof RegExp)) throw new Error("value must be RegExp");
|
if (!(this.value instanceof RegExp)) throw new Error("value must be RegExp");
|
||||||
},
|
},
|
||||||
@@ -1991,6 +2194,7 @@ var AST_RegExp = DEFNODE("RegExp", "value", {
|
|||||||
|
|
||||||
var AST_Atom = DEFNODE("Atom", null, {
|
var AST_Atom = DEFNODE("Atom", null, {
|
||||||
$documentation: "Base class for atoms",
|
$documentation: "Base class for atoms",
|
||||||
|
_equals: return_true,
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.TYPE == "Atom") throw new Error("should not instantiate AST_Atom");
|
if (this.TYPE == "Atom") throw new Error("should not instantiate AST_Atom");
|
||||||
},
|
},
|
||||||
|
|||||||
1433
lib/compress.js
1433
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -76,6 +76,7 @@ function minify(files, options) {
|
|||||||
annotations: undefined,
|
annotations: undefined,
|
||||||
compress: {},
|
compress: {},
|
||||||
enclose: false,
|
enclose: false,
|
||||||
|
expression: false,
|
||||||
ie: false,
|
ie: false,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
@@ -98,6 +99,7 @@ function minify(files, options) {
|
|||||||
if (options.validate) AST_Node.enable_validation();
|
if (options.validate) AST_Node.enable_validation();
|
||||||
var timings = options.timings && { start: Date.now() };
|
var timings = options.timings && { start: Date.now() };
|
||||||
if (options.annotations !== undefined) set_shorthand("annotations", options, [ "compress", "output" ]);
|
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.ie8) options.ie = options.ie || options.ie8;
|
||||||
if (options.ie) set_shorthand("ie", options, [ "compress", "mangle", "output", "rename" ]);
|
if (options.ie) set_shorthand("ie", options, [ "compress", "mangle", "output", "rename" ]);
|
||||||
if (options.keep_fargs) set_shorthand("keep_fargs", options, [ "compress", "mangle", "rename" ]);
|
if (options.keep_fargs) set_shorthand("keep_fargs", options, [ "compress", "mangle", "rename" ]);
|
||||||
@@ -153,13 +155,11 @@ function minify(files, options) {
|
|||||||
}, options.warnings == "verbose");
|
}, options.warnings == "verbose");
|
||||||
if (timings) timings.parse = Date.now();
|
if (timings) timings.parse = Date.now();
|
||||||
var toplevel;
|
var toplevel;
|
||||||
if (files instanceof AST_Toplevel) {
|
options.parse = options.parse || {};
|
||||||
|
if (files instanceof AST_Node) {
|
||||||
toplevel = files;
|
toplevel = files;
|
||||||
} else {
|
} else {
|
||||||
if (typeof files == "string") {
|
if (typeof files == "string") files = [ files ];
|
||||||
files = [ files ];
|
|
||||||
}
|
|
||||||
options.parse = options.parse || {};
|
|
||||||
options.parse.toplevel = null;
|
options.parse.toplevel = null;
|
||||||
var source_map_content = options.sourceMap && options.sourceMap.content;
|
var source_map_content = options.sourceMap && options.sourceMap.content;
|
||||||
if (typeof source_map_content == "string" && source_map_content != "inline") {
|
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);
|
options.parse.toplevel = toplevel = parse(files[name], options.parse);
|
||||||
if (source_map_content == "inline") {
|
if (source_map_content == "inline") {
|
||||||
var inlined_content = read_source_map(name, toplevel);
|
var inlined_content = read_source_map(name, toplevel);
|
||||||
if (inlined_content) {
|
if (inlined_content) options.sourceMap.orig[name] = parse_source_map(inlined_content);
|
||||||
options.sourceMap.orig[name] = parse_source_map(inlined_content);
|
|
||||||
}
|
|
||||||
} else if (source_map_content) {
|
} else if (source_map_content) {
|
||||||
options.sourceMap.orig[name] = source_map_content;
|
options.sourceMap.orig[name] = source_map_content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (quoted_props) {
|
if (options.parse.expression) toplevel = toplevel.wrap_expression();
|
||||||
reserve_quoted_keys(toplevel, quoted_props);
|
if (quoted_props) reserve_quoted_keys(toplevel, quoted_props);
|
||||||
}
|
|
||||||
[ "enclose", "wrap" ].forEach(function(action) {
|
[ "enclose", "wrap" ].forEach(function(action) {
|
||||||
var option = options[action];
|
var option = options[action];
|
||||||
if (!option) return;
|
if (!option) return;
|
||||||
@@ -209,6 +206,7 @@ function minify(files, options) {
|
|||||||
}
|
}
|
||||||
if (timings) timings.properties = Date.now();
|
if (timings) timings.properties = Date.now();
|
||||||
if (options.mangle && options.mangle.properties) mangle_properties(toplevel, options.mangle.properties);
|
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();
|
if (timings) timings.output = Date.now();
|
||||||
var result = {};
|
var result = {};
|
||||||
var output = defaults(options.output, {
|
var output = defaults(options.output, {
|
||||||
|
|||||||
@@ -192,6 +192,19 @@
|
|||||||
value: from_moz(M.value),
|
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) {
|
ForOfStatement: function(M) {
|
||||||
return new (M.await ? AST_ForAwaitOf : AST_ForOf)({
|
return new (M.await ? AST_ForAwaitOf : AST_ForOf)({
|
||||||
start: my_start_token(M),
|
start: my_start_token(M),
|
||||||
@@ -303,13 +316,22 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
ExportAllDeclaration: function(M) {
|
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({
|
return new AST_ExportForeign({
|
||||||
start: my_start_token(M),
|
start: start,
|
||||||
end: my_end_token(M),
|
end: end,
|
||||||
aliases: [ alias ],
|
aliases: [ M.exported ? from_moz_alias(M.exported) : new AST_String({
|
||||||
keys: [ "*" ],
|
start: start,
|
||||||
path: M.source.value,
|
value: "*",
|
||||||
|
end: end,
|
||||||
|
}) ],
|
||||||
|
keys: [ new AST_String({
|
||||||
|
start: start,
|
||||||
|
value: "*",
|
||||||
|
end: end,
|
||||||
|
}) ],
|
||||||
|
path: from_moz(M.source),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
ExportDefaultDeclaration: function(M) {
|
ExportDefaultDeclaration: function(M) {
|
||||||
@@ -346,15 +368,15 @@
|
|||||||
if (M.source) {
|
if (M.source) {
|
||||||
var aliases = [], keys = [];
|
var aliases = [], keys = [];
|
||||||
M.specifiers.forEach(function(prop) {
|
M.specifiers.forEach(function(prop) {
|
||||||
aliases.push(read_name(prop.exported));
|
aliases.push(from_moz_alias(prop.exported));
|
||||||
keys.push(read_name(prop.local));
|
keys.push(from_moz_alias(prop.local));
|
||||||
});
|
});
|
||||||
return new AST_ExportForeign({
|
return new AST_ExportForeign({
|
||||||
start: my_start_token(M),
|
start: my_start_token(M),
|
||||||
end: my_end_token(M),
|
end: my_end_token(M),
|
||||||
aliases: aliases,
|
aliases: aliases,
|
||||||
keys: keys,
|
keys: keys,
|
||||||
path: M.source.value,
|
path: from_moz(M.source),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return new AST_ExportReferences({
|
return new AST_ExportReferences({
|
||||||
@@ -362,38 +384,48 @@
|
|||||||
end: my_end_token(M),
|
end: my_end_token(M),
|
||||||
properties: M.specifiers.map(function(prop) {
|
properties: M.specifiers.map(function(prop) {
|
||||||
var sym = new AST_SymbolExport(from_moz(prop.local));
|
var sym = new AST_SymbolExport(from_moz(prop.local));
|
||||||
sym.alias = read_name(prop.exported);
|
sym.alias = from_moz_alias(prop.exported);
|
||||||
return sym;
|
return sym;
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
ImportDeclaration: function(M) {
|
ImportDeclaration: function(M) {
|
||||||
|
var start = my_start_token(M);
|
||||||
|
var end = my_end_token(M);
|
||||||
var all = null, def = null, props = null;
|
var all = null, def = null, props = null;
|
||||||
M.specifiers.forEach(function(prop) {
|
M.specifiers.forEach(function(prop) {
|
||||||
var sym = new AST_SymbolImport(from_moz(prop.local));
|
var sym = new AST_SymbolImport(from_moz(prop.local));
|
||||||
switch (prop.type) {
|
switch (prop.type) {
|
||||||
case "ImportDefaultSpecifier":
|
case "ImportDefaultSpecifier":
|
||||||
def = sym;
|
def = sym;
|
||||||
def.key = "";
|
def.key = new AST_String({
|
||||||
|
start: start,
|
||||||
|
value: "",
|
||||||
|
end: end,
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case "ImportNamespaceSpecifier":
|
case "ImportNamespaceSpecifier":
|
||||||
all = sym;
|
all = sym;
|
||||||
all.key = "*";
|
all.key = new AST_String({
|
||||||
|
start: start,
|
||||||
|
value: "*",
|
||||||
|
end: end,
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sym.key = prop.imported.name || syn.name;
|
sym.key = from_moz_alias(prop.imported);
|
||||||
if (!props) props = [];
|
if (!props) props = [];
|
||||||
props.push(sym);
|
props.push(sym);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return new AST_Import({
|
return new AST_Import({
|
||||||
start: my_start_token(M),
|
start: start,
|
||||||
end: my_end_token(M),
|
end: end,
|
||||||
all: all,
|
all: all,
|
||||||
default: def,
|
default: def,
|
||||||
properties: props,
|
properties: props,
|
||||||
path: M.source.value,
|
path: from_moz(M.source),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
ImportExpression: function(M) {
|
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) {
|
function To_Moz_ForOfStatement(is_await) {
|
||||||
return function(M) {
|
return function(M) {
|
||||||
return {
|
return {
|
||||||
@@ -780,38 +816,26 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
def_to_moz(AST_ExportForeign, function To_Moz_ExportAllDeclaration_ExportNamedDeclaration(M) {
|
def_to_moz(AST_ExportForeign, function To_Moz_ExportAllDeclaration_ExportNamedDeclaration(M) {
|
||||||
if (M.keys[0] == "*") return {
|
if (M.keys[0].value == "*") return {
|
||||||
type: "ExportAllDeclaration",
|
type: "ExportAllDeclaration",
|
||||||
exported: M.aliases[0] == "*" ? null : {
|
exported: M.aliases[0].value == "*" ? null : to_moz_alias(M.aliases[0]),
|
||||||
type: "Identifier",
|
source: to_moz(M.path),
|
||||||
name: M.aliases[0],
|
|
||||||
},
|
|
||||||
source: {
|
|
||||||
type: "Literal",
|
|
||||||
value: M.path,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
var specifiers = [];
|
var specifiers = [];
|
||||||
for (var i = 0; i < M.aliases.length; i++) {
|
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",
|
type: "ExportSpecifier",
|
||||||
exported: {
|
local: to_moz_alias(M.keys[i]),
|
||||||
type: "Identifier",
|
exported: to_moz_alias(M.aliases[i]),
|
||||||
name: M.aliases[i],
|
}));
|
||||||
},
|
|
||||||
local: {
|
|
||||||
type: "Identifier",
|
|
||||||
name: M.keys[i],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
type: "ExportNamedDeclaration",
|
type: "ExportNamedDeclaration",
|
||||||
specifiers: specifiers,
|
specifiers: specifiers,
|
||||||
source: {
|
source: to_moz(M.path),
|
||||||
type: "Literal",
|
|
||||||
value: M.path,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -819,44 +843,41 @@
|
|||||||
return {
|
return {
|
||||||
type: "ExportNamedDeclaration",
|
type: "ExportNamedDeclaration",
|
||||||
specifiers: M.properties.map(function(prop) {
|
specifiers: M.properties.map(function(prop) {
|
||||||
return {
|
return set_moz_loc({
|
||||||
|
start: prop.start,
|
||||||
|
end: prop.alias.end,
|
||||||
|
}, {
|
||||||
type: "ExportSpecifier",
|
type: "ExportSpecifier",
|
||||||
local: to_moz(prop),
|
local: to_moz(prop),
|
||||||
exported: {
|
exported: to_moz_alias(prop.alias),
|
||||||
type: "Identifier",
|
});
|
||||||
name: prop.alias,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) {
|
def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) {
|
||||||
var specifiers = M.properties ? M.properties.map(function(prop) {
|
var specifiers = M.properties ? M.properties.map(function(prop) {
|
||||||
return {
|
return set_moz_loc({
|
||||||
|
start: prop.key.start,
|
||||||
|
end: prop.end,
|
||||||
|
}, {
|
||||||
type: "ImportSpecifier",
|
type: "ImportSpecifier",
|
||||||
local: to_moz(prop),
|
local: to_moz(prop),
|
||||||
imported: {
|
imported: to_moz_alias(prop.key),
|
||||||
type: "Identifier",
|
});
|
||||||
name: prop.key,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}) : [];
|
}) : [];
|
||||||
if (M.all) specifiers.unshift({
|
if (M.all) specifiers.unshift(set_moz_loc(M.all, {
|
||||||
type: "ImportNamespaceSpecifier",
|
type: "ImportNamespaceSpecifier",
|
||||||
local: to_moz(M.all),
|
local: to_moz(M.all),
|
||||||
});
|
}));
|
||||||
if (M.default) specifiers.unshift({
|
if (M.default) specifiers.unshift(set_moz_loc(M.default, {
|
||||||
type: "ImportDefaultSpecifier",
|
type: "ImportDefaultSpecifier",
|
||||||
local: to_moz(M.default),
|
local: to_moz(M.default),
|
||||||
});
|
}));
|
||||||
return {
|
return {
|
||||||
type: "ImportDeclaration",
|
type: "ImportDeclaration",
|
||||||
specifiers: specifiers,
|
specifiers: specifiers,
|
||||||
source: {
|
source: to_moz(M.path),
|
||||||
type: "Literal",
|
|
||||||
value: M.path,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1203,6 +1224,14 @@
|
|||||||
return node;
|
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) {
|
AST_Node.from_mozilla_ast = function(node) {
|
||||||
var save_stack = FROM_MOZ_STACK;
|
var save_stack = FROM_MOZ_STACK;
|
||||||
FROM_MOZ_STACK = [];
|
FROM_MOZ_STACK = [];
|
||||||
@@ -1254,6 +1283,13 @@
|
|||||||
return node != null ? node.to_mozilla_ast() : null;
|
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) {
|
function to_moz_block(node) {
|
||||||
return {
|
return {
|
||||||
type: "BlockStatement",
|
type: "BlockStatement",
|
||||||
|
|||||||
@@ -406,10 +406,11 @@ function OutputStream(options) {
|
|||||||
print(";");
|
print(";");
|
||||||
}
|
}
|
||||||
|
|
||||||
function with_block(cont) {
|
function with_block(cont, end) {
|
||||||
print("{");
|
print("{");
|
||||||
newline();
|
newline();
|
||||||
with_indent(cont);
|
with_indent(cont);
|
||||||
|
add_mapping(end);
|
||||||
indent();
|
indent();
|
||||||
print("}");
|
print("}");
|
||||||
}
|
}
|
||||||
@@ -953,7 +954,7 @@ function OutputStream(options) {
|
|||||||
if (self.body.length > 0) {
|
if (self.body.length > 0) {
|
||||||
output.with_block(function() {
|
output.with_block(function() {
|
||||||
display_body(self.body, false, output, allow_directives);
|
display_body(self.body, false, output, allow_directives);
|
||||||
});
|
}, self.end);
|
||||||
} else print_braced_empty(self, output);
|
} else print_braced_empty(self, output);
|
||||||
}
|
}
|
||||||
DEFPRINT(AST_BlockStatement, function(output) {
|
DEFPRINT(AST_BlockStatement, function(output) {
|
||||||
@@ -1061,6 +1062,14 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
output.semicolon();
|
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) {
|
DEFPRINT(AST_ExportForeign, function(output) {
|
||||||
var self = this;
|
var self = this;
|
||||||
output.print("export");
|
output.print("export");
|
||||||
@@ -1068,7 +1077,7 @@ function OutputStream(options) {
|
|||||||
var len = self.keys.length;
|
var len = self.keys.length;
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
print_braced_empty(self, output);
|
print_braced_empty(self, output);
|
||||||
} else if (self.keys[0] == "*") {
|
} else if (self.keys[0].value == "*") {
|
||||||
print_entry(0);
|
print_entry(0);
|
||||||
} else output.with_block(function() {
|
} else output.with_block(function() {
|
||||||
output.indent();
|
output.indent();
|
||||||
@@ -1080,22 +1089,22 @@ function OutputStream(options) {
|
|||||||
print_entry(i);
|
print_entry(i);
|
||||||
}
|
}
|
||||||
output.newline();
|
output.newline();
|
||||||
});
|
}, self.end);
|
||||||
output.space();
|
output.space();
|
||||||
output.print("from");
|
output.print("from");
|
||||||
output.space();
|
output.space();
|
||||||
output.print_string(self.path, self.quote);
|
self.path.print(output);
|
||||||
output.semicolon();
|
output.semicolon();
|
||||||
|
|
||||||
function print_entry(index) {
|
function print_entry(index) {
|
||||||
var alias = self.aliases[index];
|
var alias = self.aliases[index];
|
||||||
var key = self.keys[index];
|
var key = self.keys[index];
|
||||||
output.print_name(key);
|
print_alias(key, output);
|
||||||
if (alias != key) {
|
if (alias.value != key.value) {
|
||||||
output.space();
|
output.space();
|
||||||
output.print("as");
|
output.print("as");
|
||||||
output.space();
|
output.space();
|
||||||
output.print_name(alias);
|
print_alias(alias, output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1124,7 +1133,7 @@ function OutputStream(options) {
|
|||||||
output.print("from");
|
output.print("from");
|
||||||
output.space();
|
output.space();
|
||||||
}
|
}
|
||||||
output.print_string(self.path, self.quote);
|
self.path.print(output);
|
||||||
output.semicolon();
|
output.semicolon();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1344,7 +1353,7 @@ function OutputStream(options) {
|
|||||||
if (i < last && branch.body.length > 0)
|
if (i < last && branch.body.length > 0)
|
||||||
output.newline();
|
output.newline();
|
||||||
});
|
});
|
||||||
});
|
}, self.end);
|
||||||
});
|
});
|
||||||
function print_branch_body(self, output) {
|
function print_branch_body(self, output) {
|
||||||
output.newline();
|
output.newline();
|
||||||
@@ -1464,14 +1473,12 @@ function OutputStream(options) {
|
|||||||
output.print("/*@__PURE__*/");
|
output.print("/*@__PURE__*/");
|
||||||
}
|
}
|
||||||
function print_call_args(self, output) {
|
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() {
|
output.with_parens(function() {
|
||||||
self.args.forEach(function(expr, i) {
|
self.args.forEach(function(expr, i) {
|
||||||
if (i) output.comma();
|
if (i) output.comma();
|
||||||
expr.print(output);
|
expr.print(output);
|
||||||
});
|
});
|
||||||
|
output.add_mapping(self.end);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
DEFPRINT(AST_Call, function(output) {
|
DEFPRINT(AST_Call, function(output) {
|
||||||
@@ -1507,10 +1514,11 @@ function OutputStream(options) {
|
|||||||
expr.print(output);
|
expr.print(output);
|
||||||
var prop = self.property;
|
var prop = self.property;
|
||||||
if (output.option("ie") && RESERVED_WORDS[prop]) {
|
if (output.option("ie") && RESERVED_WORDS[prop]) {
|
||||||
output.print(self.optional ? "?.[" : "[");
|
if (self.optional) output.print("?.");
|
||||||
|
output.with_square(function() {
|
||||||
output.add_mapping(self.end);
|
output.add_mapping(self.end);
|
||||||
output.print_string(prop);
|
output.print_string(prop);
|
||||||
output.print("]");
|
});
|
||||||
} else {
|
} else {
|
||||||
if (expr instanceof AST_Number && !/[ex.)]/i.test(output.last())) output.print(".");
|
if (expr instanceof AST_Number && !/[ex.)]/i.test(output.last())) output.print(".");
|
||||||
output.print(self.optional ? "?." : ".");
|
output.print(self.optional ? "?." : ".");
|
||||||
@@ -1522,9 +1530,10 @@ function OutputStream(options) {
|
|||||||
DEFPRINT(AST_Sub, function(output) {
|
DEFPRINT(AST_Sub, function(output) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.expression.print(output);
|
self.expression.print(output);
|
||||||
output.print(self.optional ? "?.[" : "[");
|
if (self.optional) output.print("?.");
|
||||||
|
output.with_square(function() {
|
||||||
self.property.print(output);
|
self.property.print(output);
|
||||||
output.print("]");
|
});
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Spread, function(output) {
|
DEFPRINT(AST_Spread, function(output) {
|
||||||
output.print("...");
|
output.print("...");
|
||||||
@@ -1543,8 +1552,10 @@ function OutputStream(options) {
|
|||||||
exp.print(output);
|
exp.print(output);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_UnaryPostfix, function(output) {
|
DEFPRINT(AST_UnaryPostfix, function(output) {
|
||||||
this.expression.print(output);
|
var self = this;
|
||||||
output.print(this.operator);
|
self.expression.print(output);
|
||||||
|
output.add_mapping(self.end);
|
||||||
|
output.print(self.operator);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Binary, function(output) {
|
DEFPRINT(AST_Binary, function(output) {
|
||||||
var self = this;
|
var self = this;
|
||||||
@@ -1637,7 +1648,8 @@ function OutputStream(options) {
|
|||||||
value.print(output);
|
value.print(output);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_DestructuredObject, function(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() {
|
if (len || rest) output.with_block(function() {
|
||||||
props.forEach(function(prop, i) {
|
props.forEach(function(prop, i) {
|
||||||
if (i) {
|
if (i) {
|
||||||
@@ -1657,8 +1669,8 @@ function OutputStream(options) {
|
|||||||
rest.print(output);
|
rest.print(output);
|
||||||
}
|
}
|
||||||
output.newline();
|
output.newline();
|
||||||
});
|
}, self.end);
|
||||||
else print_braced_empty(this, output);
|
else print_braced_empty(self, output);
|
||||||
});
|
});
|
||||||
function print_properties(self, output, no_comma) {
|
function print_properties(self, output, no_comma) {
|
||||||
var props = self.properties;
|
var props = self.properties;
|
||||||
@@ -1672,7 +1684,7 @@ function OutputStream(options) {
|
|||||||
prop.print(output);
|
prop.print(output);
|
||||||
});
|
});
|
||||||
output.newline();
|
output.newline();
|
||||||
});
|
}, self.end);
|
||||||
else print_braced_empty(self, output);
|
else print_braced_empty(self, output);
|
||||||
}
|
}
|
||||||
DEFPRINT(AST_Object, function(output) {
|
DEFPRINT(AST_Object, function(output) {
|
||||||
@@ -1734,19 +1746,19 @@ function OutputStream(options) {
|
|||||||
var name = get_symbol_name(self);
|
var name = get_symbol_name(self);
|
||||||
output.print_name(name);
|
output.print_name(name);
|
||||||
var alias = self.alias;
|
var alias = self.alias;
|
||||||
if (alias != name) {
|
if (alias.value != name) {
|
||||||
output.space();
|
output.space();
|
||||||
output.print("as");
|
output.print("as");
|
||||||
output.space();
|
output.space();
|
||||||
output.print_name(alias);
|
print_alias(alias, output);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_SymbolImport, function(output) {
|
DEFPRINT(AST_SymbolImport, function(output) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var name = get_symbol_name(self);
|
var name = get_symbol_name(self);
|
||||||
var key = self.key;
|
var key = self.key;
|
||||||
if (key && key != name) {
|
if (key.value && key.value != name) {
|
||||||
output.print_name(key);
|
print_alias(key, output);
|
||||||
output.space();
|
output.space();
|
||||||
output.print("as");
|
output.print("as");
|
||||||
output.space();
|
output.space();
|
||||||
@@ -1882,7 +1894,7 @@ function OutputStream(options) {
|
|||||||
output.indent();
|
output.indent();
|
||||||
stmt.print(output);
|
stmt.print(output);
|
||||||
output.newline();
|
output.newline();
|
||||||
});
|
}, stmt.end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----[ source map generators ]----- */
|
/* -----[ source map generators ]----- */
|
||||||
@@ -1905,22 +1917,27 @@ function OutputStream(options) {
|
|||||||
// or if we should add even more.
|
// or if we should add even more.
|
||||||
DEFMAP([
|
DEFMAP([
|
||||||
AST_Array,
|
AST_Array,
|
||||||
|
AST_Await,
|
||||||
AST_BlockStatement,
|
AST_BlockStatement,
|
||||||
AST_Catch,
|
AST_Catch,
|
||||||
AST_Constant,
|
AST_Constant,
|
||||||
AST_Debugger,
|
AST_Debugger,
|
||||||
AST_Definitions,
|
AST_Definitions,
|
||||||
AST_Destructured,
|
AST_Destructured,
|
||||||
|
AST_Directive,
|
||||||
AST_Finally,
|
AST_Finally,
|
||||||
AST_Jump,
|
AST_Jump,
|
||||||
AST_Lambda,
|
AST_Lambda,
|
||||||
AST_New,
|
AST_New,
|
||||||
AST_Object,
|
AST_Object,
|
||||||
|
AST_Spread,
|
||||||
AST_StatementWithBody,
|
AST_StatementWithBody,
|
||||||
AST_Symbol,
|
AST_Symbol,
|
||||||
AST_Switch,
|
AST_Switch,
|
||||||
AST_SwitchBranch,
|
AST_SwitchBranch,
|
||||||
AST_Try,
|
AST_Try,
|
||||||
|
AST_UnaryPrefix,
|
||||||
|
AST_Yield,
|
||||||
], function(output) {
|
], function(output) {
|
||||||
output.add_mapping(this.start);
|
output.add_mapping(this.start);
|
||||||
});
|
});
|
||||||
|
|||||||
113
lib/parse.js
113
lib/parse.js
@@ -552,16 +552,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
|
|
||||||
function handle_dot() {
|
function handle_dot() {
|
||||||
next();
|
next();
|
||||||
var ch = peek();
|
if (looking_at("..")) return token("operator", "." + next() + next());
|
||||||
if (ch == ".") {
|
return is_digit(peek().charCodeAt(0)) ? read_num(".") : token("punc", ".");
|
||||||
var op = ".";
|
|
||||||
do {
|
|
||||||
op += ".";
|
|
||||||
next();
|
|
||||||
} while (peek() == ".");
|
|
||||||
return token("operator", op);
|
|
||||||
}
|
|
||||||
return is_digit(ch.charCodeAt(0)) ? read_num(".") : token("punc", ".");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function read_word() {
|
function read_word() {
|
||||||
@@ -815,7 +807,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var statement = embed_tokens(function() {
|
var statement = embed_tokens(function(toplevel) {
|
||||||
handle_regexp();
|
handle_regexp();
|
||||||
switch (S.token.type) {
|
switch (S.token.type) {
|
||||||
case "string":
|
case "string":
|
||||||
@@ -854,15 +846,15 @@ function parse($TEXT, options) {
|
|||||||
if (S.in_async) return simple_statement();
|
if (S.in_async) return simple_statement();
|
||||||
break;
|
break;
|
||||||
case "export":
|
case "export":
|
||||||
|
if (!toplevel && options.module !== "") unexpected();
|
||||||
next();
|
next();
|
||||||
return export_();
|
return export_();
|
||||||
case "import":
|
case "import":
|
||||||
var token = peek();
|
var token = peek();
|
||||||
if (!(token.type == "punc" && /^[(.]$/.test(token.value))) {
|
if (token.type == "punc" && /^[(.]$/.test(token.value)) break;
|
||||||
|
if (!toplevel && options.module !== "") unexpected();
|
||||||
next();
|
next();
|
||||||
return import_();
|
return import_();
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "let":
|
case "let":
|
||||||
if (is_vardefs()) {
|
if (is_vardefs()) {
|
||||||
next();
|
next();
|
||||||
@@ -1064,13 +1056,13 @@ function parse($TEXT, options) {
|
|||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
function has_modifier(name) {
|
function has_modifier(name, no_nlb) {
|
||||||
if (!is("name", name)) return;
|
if (!is("name", name)) return;
|
||||||
var token = peek();
|
var token = peek();
|
||||||
if (!token) return;
|
if (!token) return;
|
||||||
if (is_token(token, "operator", "=")) return;
|
if (is_token(token, "operator", "=")) return;
|
||||||
if (token.type == "punc" && /^[(;}]$/.test(token.value)) 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();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1100,7 +1092,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
var fixed = !!has_modifier("static");
|
var fixed = !!has_modifier("static");
|
||||||
var async = has_modifier("async");
|
var async = has_modifier("async", true);
|
||||||
if (is("operator", "*")) {
|
if (is("operator", "*")) {
|
||||||
next();
|
next();
|
||||||
var internal = is("name") && /^#/.test(S.token.value);
|
var internal = is("name") && /^#/.test(S.token.value);
|
||||||
@@ -1442,28 +1434,41 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function is_alias() {
|
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_() {
|
function export_() {
|
||||||
if (is("operator", "*")) {
|
if (is("operator", "*")) {
|
||||||
|
var key = S.token;
|
||||||
|
var alias = key;
|
||||||
next();
|
next();
|
||||||
var alias = "*";
|
|
||||||
if (is("name", "as")) {
|
if (is("name", "as")) {
|
||||||
next();
|
next();
|
||||||
if (!is_alias()) expect_token("name");
|
if (!is_alias()) expect_token("name");
|
||||||
alias = S.token.value;
|
alias = S.token;
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
expect_token("name", "from");
|
expect_token("name", "from");
|
||||||
var path = S.token;
|
|
||||||
expect_token("string");
|
|
||||||
semicolon();
|
|
||||||
return new AST_ExportForeign({
|
return new AST_ExportForeign({
|
||||||
aliases: [ alias ],
|
aliases: [ make_string(alias) ],
|
||||||
keys: [ "*" ],
|
keys: [ make_string(key) ],
|
||||||
path: path.value,
|
path: as_path(),
|
||||||
quote: path.quote,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (is("punc", "{")) {
|
if (is("punc", "{")) {
|
||||||
@@ -1477,26 +1482,20 @@ function parse($TEXT, options) {
|
|||||||
if (is("name", "as")) {
|
if (is("name", "as")) {
|
||||||
next();
|
next();
|
||||||
if (!is_alias()) expect_token("name");
|
if (!is_alias()) expect_token("name");
|
||||||
aliases.push(S.token.value);
|
aliases.push(S.token);
|
||||||
next();
|
next();
|
||||||
} else {
|
} else {
|
||||||
aliases.push(key.value);
|
aliases.push(key);
|
||||||
}
|
}
|
||||||
if (!is("punc", "}")) expect(",");
|
if (!is("punc", "}")) expect(",");
|
||||||
}
|
}
|
||||||
expect("}");
|
expect("}");
|
||||||
if (is("name", "from")) {
|
if (is("name", "from")) {
|
||||||
next();
|
next();
|
||||||
var path = S.token;
|
|
||||||
expect_token("string");
|
|
||||||
semicolon();
|
|
||||||
return new AST_ExportForeign({
|
return new AST_ExportForeign({
|
||||||
aliases: aliases,
|
aliases: aliases.map(make_string),
|
||||||
keys: keys.map(function(token) {
|
keys: keys.map(make_string),
|
||||||
return token.value;
|
path: as_path(),
|
||||||
}),
|
|
||||||
path: path.value,
|
|
||||||
quote: path.quote,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
semicolon();
|
semicolon();
|
||||||
@@ -1504,7 +1503,7 @@ function parse($TEXT, options) {
|
|||||||
properties: keys.map(function(token, index) {
|
properties: keys.map(function(token, index) {
|
||||||
if (!is_token(token, "name")) token_error(token, "Name expected");
|
if (!is_token(token, "name")) token_error(token, "Name expected");
|
||||||
var sym = _make_symbol(AST_SymbolExport, token);
|
var sym = _make_symbol(AST_SymbolExport, token);
|
||||||
sym.alias = aliases[index];
|
sym.alias = make_string(aliases[index]);
|
||||||
return sym;
|
return sym;
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
@@ -1594,26 +1593,42 @@ function parse($TEXT, options) {
|
|||||||
var all = null;
|
var all = null;
|
||||||
var def = as_symbol(AST_SymbolImport, true);
|
var def = as_symbol(AST_SymbolImport, true);
|
||||||
var props = null;
|
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", "*")) {
|
if (is("operator", "*")) {
|
||||||
|
var key = S.token;
|
||||||
next();
|
next();
|
||||||
expect_token("name", "as");
|
expect_token("name", "as");
|
||||||
all = as_symbol(AST_SymbolImport);
|
all = as_symbol(AST_SymbolImport);
|
||||||
all.key = "*";
|
all.key = make_string(key);
|
||||||
} else {
|
} else {
|
||||||
expect("{");
|
expect("{");
|
||||||
props = [];
|
props = [];
|
||||||
while (is_alias()) {
|
while (is_alias()) {
|
||||||
var alias;
|
var alias;
|
||||||
if (is_token(peek(), "name", "as")) {
|
if (is_token(peek(), "name", "as")) {
|
||||||
var key = S.token.value;
|
var key = S.token;
|
||||||
next();
|
next();
|
||||||
next();
|
next();
|
||||||
alias = as_symbol(AST_SymbolImport);
|
alias = as_symbol(AST_SymbolImport);
|
||||||
alias.key = key;
|
alias.key = make_string(key);
|
||||||
} else {
|
} else {
|
||||||
alias = as_symbol(AST_SymbolImport);
|
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);
|
props.push(alias);
|
||||||
if (!is("punc", "}")) expect(",");
|
if (!is("punc", "}")) expect(",");
|
||||||
@@ -1622,15 +1637,11 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (all || def || props) expect_token("name", "from");
|
if (all || def || props) expect_token("name", "from");
|
||||||
var path = S.token;
|
|
||||||
expect_token("string");
|
|
||||||
semicolon();
|
|
||||||
return new AST_Import({
|
return new AST_Import({
|
||||||
all: all,
|
all: all,
|
||||||
default: def,
|
default: def,
|
||||||
path: path.value,
|
path: as_path(),
|
||||||
properties: props,
|
properties: props,
|
||||||
quote: path.quote,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1808,7 +1819,7 @@ function parse($TEXT, options) {
|
|||||||
ret = new AST_BigInt({ value: value });
|
ret = new AST_BigInt({ value: value });
|
||||||
break;
|
break;
|
||||||
case "string":
|
case "string":
|
||||||
ret = new AST_String({ value : value, quote : tok.quote });
|
ret = new AST_String({ value: value, quote: tok.quote });
|
||||||
break;
|
break;
|
||||||
case "regexp":
|
case "regexp":
|
||||||
ret = new AST_RegExp({ value: value });
|
ret = new AST_RegExp({ value: value });
|
||||||
@@ -2563,7 +2574,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
S.input.push_directives_stack();
|
S.input.push_directives_stack();
|
||||||
while (!is("eof"))
|
while (!is("eof"))
|
||||||
body.push(statement());
|
body.push(statement(true));
|
||||||
S.input.pop_directives_stack();
|
S.input.pop_directives_stack();
|
||||||
var end = prev() || start;
|
var end = prev() || start;
|
||||||
var toplevel = options.toplevel;
|
var toplevel = options.toplevel;
|
||||||
|
|||||||
@@ -43,10 +43,11 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var builtins = function() {
|
function get_builtins() {
|
||||||
var names = new Dictionary();
|
var names = new Dictionary();
|
||||||
// NaN will be included due to Number.NaN
|
// constants
|
||||||
[
|
[
|
||||||
|
"NaN",
|
||||||
"null",
|
"null",
|
||||||
"true",
|
"true",
|
||||||
"false",
|
"false",
|
||||||
@@ -54,30 +55,72 @@ var builtins = function() {
|
|||||||
"-Infinity",
|
"-Infinity",
|
||||||
"undefined",
|
"undefined",
|
||||||
].forEach(add);
|
].forEach(add);
|
||||||
|
// global functions
|
||||||
[
|
[
|
||||||
Array,
|
"encodeURI",
|
||||||
Boolean,
|
"encodeURIComponent",
|
||||||
Date,
|
"escape",
|
||||||
Error,
|
"eval",
|
||||||
Function,
|
"decodeURI",
|
||||||
Math,
|
"decodeURIComponent",
|
||||||
Number,
|
"isFinite",
|
||||||
Object,
|
"isNaN",
|
||||||
RegExp,
|
"parseFloat",
|
||||||
String,
|
"parseInt",
|
||||||
].forEach(function(ctor) {
|
"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);
|
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(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) {
|
function add(name) {
|
||||||
names.set(name, true);
|
names.set(name, true);
|
||||||
}
|
}
|
||||||
}();
|
}
|
||||||
|
|
||||||
function reserve_quoted_keys(ast, reserved) {
|
function reserve_quoted_keys(ast, reserved) {
|
||||||
ast.walk(new TreeWalker(function(node) {
|
ast.walk(new TreeWalker(function(node) {
|
||||||
@@ -116,7 +159,7 @@ function mangle_properties(ast, options) {
|
|||||||
reserved: null,
|
reserved: null,
|
||||||
}, true);
|
}, 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) {
|
if (Array.isArray(options.reserved)) options.reserved.forEach(function(name) {
|
||||||
reserved.set(name, true);
|
reserved.set(name, true);
|
||||||
});
|
});
|
||||||
|
|||||||
11
lib/scope.js
11
lib/scope.js
@@ -286,7 +286,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
// ensure mangling works if `catch` reuses a scope variable
|
// ensure mangling works if `catch` reuses a scope variable
|
||||||
var redef = def.redefined();
|
var redef = def.redefined();
|
||||||
if (redef) for (var s = node.scope; s; s = s.parent_scope) {
|
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;
|
if (s === redef.scope) break;
|
||||||
}
|
}
|
||||||
} else if (node instanceof AST_SymbolConst) {
|
} else if (node instanceof AST_SymbolConst) {
|
||||||
@@ -480,7 +480,7 @@ AST_Lambda.DEFMETHOD("init_vars", function(parent_scope) {
|
|||||||
AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
||||||
var def = this.definition();
|
var def = this.definition();
|
||||||
for (var s = this.scope; s; s = s.parent_scope) {
|
for (var s = this.scope; s; s = s.parent_scope) {
|
||||||
push_uniq(s.enclosed, def);
|
if (!push_uniq(s.enclosed, def)) break;
|
||||||
if (!options) {
|
if (!options) {
|
||||||
s._var_names = undefined;
|
s._var_names = undefined;
|
||||||
} else {
|
} else {
|
||||||
@@ -704,7 +704,12 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|||||||
}
|
}
|
||||||
redefined.push(def);
|
redefined.push(def);
|
||||||
def.references.forEach(reference);
|
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;
|
return true;
|
||||||
|
|
||||||
function reference(sym) {
|
function reference(sym) {
|
||||||
|
|||||||
@@ -127,8 +127,10 @@ function push_uniq(array, el) {
|
|||||||
|
|
||||||
function string_template(text, props) {
|
function string_template(text, props) {
|
||||||
return text.replace(/\{([^{}]+)\}/g, function(str, p) {
|
return text.replace(/\{([^{}]+)\}/g, function(str, p) {
|
||||||
var value = props[p];
|
var value = p == "this" ? props : props[p];
|
||||||
return value instanceof AST_Node ? value.print_to_string() : value;
|
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",
|
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "3.16.1",
|
"version": "3.17.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~8.2.1",
|
"acorn": "~8.7.1",
|
||||||
"semver": "~6.3.0"
|
"semver": "~6.3.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -60,8 +60,9 @@ function log() {
|
|||||||
console.log("%s", tmpl.apply(null, arguments));
|
console.log("%s", tmpl.apply(null, arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
function make_code(ast, options) {
|
function make_code(ast, options, expression) {
|
||||||
var stream = U.OutputStream(options);
|
var stream = U.OutputStream(options);
|
||||||
|
if (expression) ast = ast.clone(true).unwrap_expression();
|
||||||
ast.print(stream);
|
ast.print(stream);
|
||||||
return stream.get();
|
return stream.get();
|
||||||
}
|
}
|
||||||
@@ -69,7 +70,7 @@ function make_code(ast, options) {
|
|||||||
function parse_test(file) {
|
function parse_test(file) {
|
||||||
var script = fs.readFileSync(file, "utf8");
|
var script = fs.readFileSync(file, "utf8");
|
||||||
try {
|
try {
|
||||||
var ast = U.parse(script, { filename: file });
|
var ast = U.parse(script, { filename: file, module: "" });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Caught error while parsing tests in " + file);
|
console.error("Caught error while parsing tests in " + file);
|
||||||
console.error(e);
|
console.error(e);
|
||||||
@@ -178,9 +179,18 @@ function parse_test(file) {
|
|||||||
|
|
||||||
// Try to reminify original input with standard options
|
// Try to reminify original input with standard options
|
||||||
// to see if it matches expect_stdout.
|
// 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++) {
|
for (var i = 0; i < minify_options.length; i++) {
|
||||||
var options = JSON.parse(minify_options[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_fargs",
|
||||||
"keep_fnames",
|
"keep_fnames",
|
||||||
@@ -210,7 +220,7 @@ function reminify(orig_options, input_code, input_formatted, stdout) {
|
|||||||
} else {
|
} else {
|
||||||
var toplevel = sandbox.has_toplevel(options);
|
var toplevel = sandbox.has_toplevel(options);
|
||||||
var expected = stdout[toplevel ? 1 : 0];
|
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) {
|
if (typeof expected != "string" && typeof actual != "string" && expected.name == actual.name) {
|
||||||
actual = expected;
|
actual = expected;
|
||||||
}
|
}
|
||||||
@@ -245,18 +255,23 @@ function reminify(orig_options, input_code, input_formatted, stdout) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function run_code(expression, code, toplevel) {
|
||||||
|
return sandbox.run_code(expression ? "console.log(" + code + ");" : code, toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
function test_case(test) {
|
function test_case(test) {
|
||||||
log(" Running test [{name}]", { name: test.name });
|
log(" Running test [{name}]", { name: test.name });
|
||||||
U.AST_Node.enable_validation();
|
U.AST_Node.enable_validation();
|
||||||
var output_options = test.beautify || {};
|
var output_options = test.beautify || {};
|
||||||
var expect;
|
var expect;
|
||||||
if (test.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 {
|
} else {
|
||||||
expect = test.expect_exact;
|
expect = test.expect_exact;
|
||||||
}
|
}
|
||||||
var input = to_toplevel(test.input, test.mangle);
|
var input = to_toplevel(test.input, test.mangle, test.expression);
|
||||||
var input_code = make_code(input);
|
var input_code = make_code(input, {}, test.expression);
|
||||||
var input_formatted = make_code(test.input, {
|
var input_formatted = make_code(test.input, {
|
||||||
annotations: true,
|
annotations: true,
|
||||||
beautify: true,
|
beautify: true,
|
||||||
@@ -266,7 +281,7 @@ function test_case(test) {
|
|||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
input.validate_ast();
|
input.validate_ast();
|
||||||
U.parse(input_code);
|
U.parse(input_code, { expression: test.expression });
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
log([
|
log([
|
||||||
"!!! Cannot parse input",
|
"!!! Cannot parse input",
|
||||||
@@ -310,7 +325,7 @@ function test_case(test) {
|
|||||||
output.mangle_names(test.mangle);
|
output.mangle_names(test.mangle);
|
||||||
if (test.mangle.properties) U.mangle_properties(output, test.mangle.properties);
|
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();
|
U.AST_Node.log_function();
|
||||||
if (expect != output_code) {
|
if (expect != output_code) {
|
||||||
log([
|
log([
|
||||||
@@ -333,7 +348,7 @@ function test_case(test) {
|
|||||||
// expect == output
|
// expect == output
|
||||||
try {
|
try {
|
||||||
output.validate_ast();
|
output.validate_ast();
|
||||||
U.parse(output_code);
|
U.parse(output_code, { expression: test.expression });
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
log([
|
log([
|
||||||
"!!! Test matched expected result but cannot parse output",
|
"!!! Test matched expected result but cannot parse output",
|
||||||
@@ -377,7 +392,7 @@ function test_case(test) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (test.expect_stdout && (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
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({
|
var toplevel = sandbox.has_toplevel({
|
||||||
compress: test.options,
|
compress: test.options,
|
||||||
mangle: test.mangle
|
mangle: test.mangle
|
||||||
@@ -406,7 +421,7 @@ function test_case(test) {
|
|||||||
});
|
});
|
||||||
return false;
|
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)) {
|
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
||||||
log([
|
log([
|
||||||
"!!! failed",
|
"!!! failed",
|
||||||
@@ -427,7 +442,7 @@ function test_case(test) {
|
|||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!reminify(test.options, input_code, input_formatted, stdout)) {
|
if (!reminify(test.expression, test.options, input_code, input_formatted, stdout)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -438,20 +453,29 @@ function tmpl() {
|
|||||||
return U.string_template.apply(null, arguments);
|
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");
|
if (!(input instanceof U.AST_BlockStatement)) throw new Error("Unsupported input syntax");
|
||||||
var directive = true;
|
|
||||||
var offset = input.start.line;
|
var offset = input.start.line;
|
||||||
var tokens = [];
|
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 (U.push_uniq(tokens, node.start)) node.start.line -= offset;
|
||||||
if (!directive || node === input) return;
|
}));
|
||||||
|
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) {
|
if (node instanceof U.AST_SimpleStatement && node.body instanceof U.AST_String) {
|
||||||
return new U.AST_Directive(node.body);
|
return new U.AST_Directive(node.body);
|
||||||
} else {
|
|
||||||
directive = false;
|
|
||||||
}
|
}
|
||||||
|
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);
|
toplevel.figure_out_scope(mangle_options);
|
||||||
return toplevel;
|
return toplevel;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1073,7 +1073,7 @@ issue_5414_2: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_5416: {
|
issue_5416_1: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -1095,10 +1095,11 @@ issue_5416: {
|
|||||||
expect: {
|
expect: {
|
||||||
var f = () => {
|
var f = () => {
|
||||||
{
|
{
|
||||||
arguments = void 0;
|
|
||||||
console;
|
console;
|
||||||
|
arguments = void 0,
|
||||||
console.log(arguments);
|
console.log(arguments);
|
||||||
var arguments;
|
var arguments;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
f();
|
f();
|
||||||
@@ -1107,6 +1108,97 @@ issue_5416: {
|
|||||||
node_version: ">=4"
|
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: {
|
issue_5495: {
|
||||||
input: {
|
input: {
|
||||||
console.log((() => {
|
console.log((() => {
|
||||||
|
|||||||
@@ -1046,6 +1046,60 @@ collapse_vars_3: {
|
|||||||
node_version: ">=8"
|
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: {
|
collapse_property_lambda: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -3021,3 +3075,157 @@ issue_5506: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=8"
|
node_version: ">=8"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5528_1: {
|
||||||
|
options = {
|
||||||
|
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 = {
|
||||||
|
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 = {
|
||||||
|
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 = {
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -241,6 +241,94 @@ class_super: {
|
|||||||
node_version: ">=4"
|
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: {
|
static_init: {
|
||||||
input: {
|
input: {
|
||||||
var a = "foo";
|
var a = "foo";
|
||||||
@@ -658,6 +746,56 @@ separate_name: {
|
|||||||
node_version: ">=4"
|
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: {
|
static_side_effects: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
@@ -3330,3 +3468,113 @@ issue_5512: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=16"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -9979,3 +9979,25 @@ issue_5396: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -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: {
|
cond_1: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
@@ -1261,6 +1433,398 @@ condition_matches_alternative: {
|
|||||||
expect_stdout: "null 0 false 5"
|
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: {
|
delete_conditional_1: {
|
||||||
options = {
|
options = {
|
||||||
booleans: true,
|
booleans: true,
|
||||||
@@ -1731,7 +2295,7 @@ issue_3576: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_3668: {
|
issue_3668_1: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
@@ -1748,6 +2312,38 @@ issue_3668: {
|
|||||||
}
|
}
|
||||||
console.log(f());
|
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: {
|
expect: {
|
||||||
function f() {
|
function f() {
|
||||||
try {
|
try {
|
||||||
@@ -1756,6 +2352,7 @@ issue_3668: {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
return "FAIL";
|
return "FAIL";
|
||||||
}
|
}
|
||||||
|
FAIL;
|
||||||
}
|
}
|
||||||
console.log(f());
|
console.log(f());
|
||||||
}
|
}
|
||||||
@@ -2062,3 +2659,176 @@ issue_5334_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -142,6 +142,80 @@ if_dead_branch: {
|
|||||||
expect_stdout: "undefined"
|
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: {
|
merge_vars_1: {
|
||||||
options = {
|
options = {
|
||||||
merge_vars: true,
|
merge_vars: true,
|
||||||
@@ -579,6 +653,37 @@ dead_block_after_return: {
|
|||||||
expect_stdout: true
|
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: {
|
do_if_continue_1: {
|
||||||
options = {
|
options = {
|
||||||
if_return: true,
|
if_return: true,
|
||||||
@@ -1872,3 +1977,170 @@ issue_5476: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -180,6 +180,26 @@ collapse_arg_sequence: {
|
|||||||
node_version: ">=6"
|
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: {
|
collapse_value_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -541,7 +561,7 @@ inline_side_effects_2: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 42;
|
var a = 42;
|
||||||
[ [].e = --a ] = [ console ];
|
[ [][0] = --a ] = [ console ];
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
@@ -1170,6 +1190,49 @@ mangle_arrow_2_toplevel: {
|
|||||||
node_version: ">=6.9.3"
|
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: {
|
issue_4444: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -1558,7 +1621,7 @@ issue_4502_4: {
|
|||||||
(function(a, b = console.log("FAIL")) {})(..."" + console.log(42));
|
(function(a, b = console.log("FAIL")) {})(..."" + console.log(42));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
[ , [].e = console.log("FAIL") ] = [ ..."" + console.log(42) ];
|
[ , [][0] = console.log("FAIL") ] = [ ..."" + console.log(42) ];
|
||||||
}
|
}
|
||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
@@ -1655,7 +1718,7 @@ issue_4540: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_4548: {
|
issue_4548_1: {
|
||||||
options = {
|
options = {
|
||||||
merge_vars: true,
|
merge_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
@@ -1681,6 +1744,32 @@ issue_4548: {
|
|||||||
node_version: ">=6"
|
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: {
|
issue_4588_1_unused: {
|
||||||
options = {
|
options = {
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -2023,7 +2112,7 @@ issue_5246_1: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
expect_warnings: [
|
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"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
@@ -2183,7 +2272,7 @@ issue_5340_2: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a;
|
var a;
|
||||||
[ [].e = 0 ] = [ ({ p: a } = true).q ];
|
[ [][0] = 0 ] = [ ({ p: a } = true).q ];
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
@@ -2462,3 +2551,494 @@ issue_5485: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=6"
|
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 b, a = "foo";
|
||||||
|
console.log(a, f());
|
||||||
|
})("bar");
|
||||||
|
}
|
||||||
|
expect_stdout: "foo bar"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|||||||
@@ -472,6 +472,93 @@ funarg_collapse_vars_3: {
|
|||||||
node_version: ">=6"
|
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: {
|
funarg_reduce_vars_1: {
|
||||||
options = {
|
options = {
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -1815,8 +1902,8 @@ issue_4288: {
|
|||||||
console.log(typeof b);
|
console.log(typeof b);
|
||||||
}()]: a,
|
}()]: a,
|
||||||
}) {
|
}) {
|
||||||
var b = a;
|
var a = a;
|
||||||
b++;
|
a++;
|
||||||
}
|
}
|
||||||
f(0);
|
f(0);
|
||||||
}
|
}
|
||||||
@@ -1989,17 +2076,16 @@ issue_4312: {
|
|||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a;
|
|
||||||
b = "PASS",
|
b = "PASS",
|
||||||
c = "FAIL",
|
c = "FAIL",
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
[a = b]: d,
|
[c = b]: d,
|
||||||
},
|
},
|
||||||
] = [ c && c ],
|
] = [ c && c ],
|
||||||
void 0;
|
void 0;
|
||||||
var b, c, d;
|
var b, c, d;
|
||||||
console.log(a);
|
console.log(c);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
@@ -3497,7 +3583,7 @@ issue_5314_2: {
|
|||||||
A = this;
|
A = this;
|
||||||
new function() {
|
new function() {
|
||||||
[ {
|
[ {
|
||||||
[console.log(this === A ? "FAIL" : "PASS")]: [].e,
|
[console.log(this === A ? "FAIL" : "PASS")]: [][0],
|
||||||
} ] = [ 42 ];
|
} ] = [ 42 ];
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
@@ -3646,3 +3732,114 @@ issue_5485: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=6"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -131,19 +131,34 @@ valid_after_invalid_2: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
issue_5368_1: {
|
issue_5368_1: {
|
||||||
|
expression = true
|
||||||
options = {
|
options = {
|
||||||
directives: true,
|
directives: true,
|
||||||
expression: true,
|
expression: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"foo";
|
"foo"
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"foo";
|
|
||||||
}
|
}
|
||||||
|
expect_exact: '"foo"'
|
||||||
|
expect_stdout: "foo"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_5368_2: {
|
issue_5368_2: {
|
||||||
|
expression = true
|
||||||
|
options = {
|
||||||
|
directives: true,
|
||||||
|
expression: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
"foo";
|
||||||
|
})()
|
||||||
|
}
|
||||||
|
expect_exact: "function(){}()"
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5368_3: {
|
||||||
options = {
|
options = {
|
||||||
directives: true,
|
directives: true,
|
||||||
expression: true,
|
expression: true,
|
||||||
|
|||||||
@@ -3685,3 +3685,85 @@ issue_5271: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "42"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -3390,3 +3390,29 @@ issue_5380: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
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";'
|
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: {
|
same_quotes: {
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
|
|||||||
@@ -629,7 +629,7 @@ inline_binary_and: {
|
|||||||
return void "moo";
|
return void "moo";
|
||||||
return;
|
return;
|
||||||
} else
|
} else
|
||||||
return;
|
return void 0;
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
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: {
|
issue_3833_1: {
|
||||||
options = {
|
options = {
|
||||||
inline: 3,
|
inline: 3,
|
||||||
@@ -5582,7 +5616,7 @@ issue_3835: {
|
|||||||
return f();
|
return f();
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: RangeError("Maximum call stack size exceeded")
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_3836_1: {
|
issue_3836_1: {
|
||||||
@@ -7835,7 +7869,7 @@ issue_5249_1: {
|
|||||||
while (console.log("FAIL 2"));
|
while (console.log("FAIL 2"));
|
||||||
return;
|
return;
|
||||||
} else
|
} else
|
||||||
return;
|
return void 0;
|
||||||
throw "FAIL 3";
|
throw "FAIL 3";
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
@@ -8646,3 +8680,42 @@ module_inline: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "true"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,17 @@ default_keys: {
|
|||||||
expect_exact: 'import foo,{bar}from"baz";'
|
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: {
|
dynamic: {
|
||||||
input: {
|
input: {
|
||||||
(async a => await import(a))("foo").then(bar);
|
(async a => await import(a))("foo").then(bar);
|
||||||
@@ -227,3 +238,33 @@ issue_4708_2: {
|
|||||||
import a from "foo";
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -110,7 +110,9 @@ numeric_literal: {
|
|||||||
|
|
||||||
identifier: {
|
identifier: {
|
||||||
mangle = {
|
mangle = {
|
||||||
properties: true,
|
properties: {
|
||||||
|
builtins: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var obj = {
|
var obj = {
|
||||||
@@ -209,37 +211,37 @@ identifier: {
|
|||||||
B: 28,
|
B: 28,
|
||||||
C: 29,
|
C: 29,
|
||||||
D: 30,
|
D: 30,
|
||||||
F: 31,
|
E: 31,
|
||||||
G: 32,
|
F: 32,
|
||||||
false: 33,
|
G: 33,
|
||||||
null: 34,
|
H: 34,
|
||||||
true: 35,
|
I: 35,
|
||||||
H: 36,
|
J: 36,
|
||||||
I: 37,
|
K: 37,
|
||||||
J: 38,
|
L: 38,
|
||||||
K: 39,
|
M: 39,
|
||||||
L: 40,
|
N: 40,
|
||||||
M: 41,
|
O: 41,
|
||||||
N: 42,
|
P: 42,
|
||||||
O: 43,
|
Q: 43,
|
||||||
P: 44,
|
R: 44,
|
||||||
Q: 45,
|
S: 45,
|
||||||
R: 46,
|
T: 46,
|
||||||
S: 47,
|
U: 47,
|
||||||
T: 48,
|
V: 48,
|
||||||
U: 49,
|
W: 49,
|
||||||
V: 50,
|
X: 50,
|
||||||
W: 51,
|
Y: 51,
|
||||||
X: 52,
|
Z: 52,
|
||||||
Y: 53,
|
$: 53,
|
||||||
Z: 54,
|
_: 54,
|
||||||
$: 55,
|
ee: 55,
|
||||||
_: 56,
|
te: 56,
|
||||||
ee: 57,
|
ne: 57,
|
||||||
te: 58,
|
ae: 58,
|
||||||
ne: 59,
|
ie: 59,
|
||||||
ae: 60,
|
oe: 60,
|
||||||
ie: 61,
|
re: 61,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ safe_undefined: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
negate_iife_3: {
|
negate_iife_3: {
|
||||||
|
expression = true
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
expression: true,
|
expression: true,
|
||||||
@@ -123,6 +124,7 @@ negate_iife_3: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
negate_iife_3_off: {
|
negate_iife_3_off: {
|
||||||
|
expression = true
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
expression: true,
|
expression: true,
|
||||||
@@ -203,6 +205,7 @@ negate_iife_5_off: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
issue_1254_negate_iife_true: {
|
issue_1254_negate_iife_true: {
|
||||||
|
expression = true
|
||||||
options = {
|
options = {
|
||||||
expression: true,
|
expression: true,
|
||||||
inline: 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
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1254_negate_iife_nested: {
|
issue_1254_negate_iife_nested: {
|
||||||
|
expression = true
|
||||||
options = {
|
options = {
|
||||||
expression: true,
|
expression: true,
|
||||||
inline: 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: {
|
negate_iife_issue_1073: {
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ drop_console_2: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
drop_value: {
|
drop_value: {
|
||||||
|
expression = true
|
||||||
options = {
|
options = {
|
||||||
expression: true,
|
expression: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -106,6 +107,7 @@ wrongly_optimized: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
negate_iife_1: {
|
negate_iife_1: {
|
||||||
|
expression = true
|
||||||
options = {
|
options = {
|
||||||
expression: true,
|
expression: true,
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
@@ -119,6 +121,7 @@ negate_iife_1: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
negate_iife_3: {
|
negate_iife_3: {
|
||||||
|
expression = true
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
expression: true,
|
expression: true,
|
||||||
@@ -133,6 +136,7 @@ negate_iife_3: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
negate_iife_3_off: {
|
negate_iife_3_off: {
|
||||||
|
expression = true
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
expression: true,
|
expression: true,
|
||||||
@@ -215,6 +219,7 @@ negate_iife_5_off: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
issue_1254_negate_iife_true: {
|
issue_1254_negate_iife_true: {
|
||||||
|
expression = true
|
||||||
options = {
|
options = {
|
||||||
expression: true,
|
expression: true,
|
||||||
negate_iife: 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
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1254_negate_iife_nested: {
|
issue_1254_negate_iife_nested: {
|
||||||
|
expression = true
|
||||||
options = {
|
options = {
|
||||||
expression: true,
|
expression: true,
|
||||||
negate_iife: 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
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ labels_5: {
|
|||||||
labels_6: {
|
labels_6: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
out: break out;
|
out: break out;
|
||||||
@@ -208,6 +209,59 @@ labels_10: {
|
|||||||
expect_stdout: "PASS"
|
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: {
|
issue_4466_1: {
|
||||||
mangle = {
|
mangle = {
|
||||||
v8: false,
|
v8: false,
|
||||||
@@ -327,3 +381,53 @@ issue_4466_2_toplevel_v8: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
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"
|
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: {
|
merge_vars_1: {
|
||||||
options = {
|
options = {
|
||||||
merge_vars: true,
|
merge_vars: true,
|
||||||
@@ -892,6 +982,40 @@ if_return_2: {
|
|||||||
node_version: ">=4"
|
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: {
|
do_if_continue_1: {
|
||||||
options = {
|
options = {
|
||||||
if_return: true,
|
if_return: true,
|
||||||
@@ -1625,7 +1749,7 @@ issue_4438: {
|
|||||||
function f() {
|
function f() {
|
||||||
if (console) {
|
if (console) {
|
||||||
let a = console.log;
|
let a = console.log;
|
||||||
void a("PASS");
|
a("PASS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f();
|
f();
|
||||||
@@ -1998,3 +2122,51 @@ issue_5476: {
|
|||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
node_version: ">=4"
|
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: {
|
issue_5266: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ mangle_unquoted_properties: {
|
|||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
properties: {
|
properties: {
|
||||||
|
builtins: true,
|
||||||
keep_quoted: true,
|
keep_quoted: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -305,6 +306,7 @@ mangle_debug_suffix_keep_quoted: {
|
|||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
properties: {
|
properties: {
|
||||||
|
builtins: true,
|
||||||
debug: "XYZ",
|
debug: "XYZ",
|
||||||
keep_quoted: true,
|
keep_quoted: true,
|
||||||
reserved: [],
|
reserved: [],
|
||||||
|
|||||||
@@ -648,7 +648,7 @@ drop_new_function: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
void ([ ... {
|
void ([ ... {
|
||||||
[console.log("PASS")]: [].e,
|
[console.log("PASS")]: [][0],
|
||||||
}] = []);
|
}] = []);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -1363,3 +1363,264 @@ issue_5391: {
|
|||||||
expect_stdout: "NaN"
|
expect_stdout: "NaN"
|
||||||
node_version: ">=8.3.0"
|
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"
|
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: {
|
drop_value: {
|
||||||
options = {
|
options = {
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
|
|||||||
@@ -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: {
|
collapse_vars_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -1194,3 +1203,53 @@ issue_5382: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=8.3.0"
|
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"
|
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 (w) {
|
||||||
if (y) return;
|
if (y) return;
|
||||||
} else if (z) return;
|
} else if (z) return;
|
||||||
return x == y || (x && w(), y && z()), !0;
|
return x != y && (x && w(), y && z()), !0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -613,3 +613,35 @@ issue_4954: {
|
|||||||
]
|
]
|
||||||
node_version: ">=4"
|
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") ]);
|
})([ console.log("baz") ]);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
[ [ , [].e = console.log("foo") ] ] = [ [ console.log("baz") ] ];
|
[ [ , [][0] = console.log("foo") ] ] = [ [ console.log("baz") ] ];
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"baz",
|
"baz",
|
||||||
@@ -1183,6 +1183,35 @@ issue_4641_2: {
|
|||||||
node_version: ">=10"
|
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: {
|
issue_4769_1: {
|
||||||
options = {
|
options = {
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -1467,6 +1496,80 @@ issue_5385_2: {
|
|||||||
node_version: ">=10"
|
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: {
|
issue_5425: {
|
||||||
options = {
|
options = {
|
||||||
assignments: true,
|
assignments: true,
|
||||||
@@ -1562,3 +1665,73 @@ issue_5506: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=4"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -38,4 +38,4 @@ var _require = require("bar"), foo = _require.foo;
|
|||||||
var _require2 = require("world"), hello = _require2.hello;
|
var _require2 = require("world"), hello = _require2.hello;
|
||||||
|
|
||||||
foo.x.apply(foo, _toConsumableArray(foo.y(hello.z)));
|
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);
|
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";
|
"aaaaaaaaaaaaaaaa";
|
||||||
a(err,data),a(err,
|
a(err,data),a(err,
|
||||||
data)}
|
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);
|
console.log(3);
|
||||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSJ9
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSxDQUFHIn0=
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
|
|
||||||
var config = {
|
var config = {
|
||||||
limit: 10000,
|
|
||||||
timeout: function(limit) {
|
timeout: function(limit) {
|
||||||
this.limit = limit;
|
this.limit = limit + lag;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
var lag = +process.env["UGLIFY_GITHUB_LAG"] || 0;
|
||||||
var tasks = [];
|
var tasks = [];
|
||||||
var titles = [];
|
var titles = [];
|
||||||
|
config.timeout(10000);
|
||||||
describe = function(title, fn) {
|
describe = function(title, fn) {
|
||||||
config = Object.create(config);
|
config = Object.create(config);
|
||||||
titles.push(title);
|
titles.push(title);
|
||||||
@@ -21,10 +22,11 @@ it = function(title, fn) {
|
|||||||
fn.titles.push(title);
|
fn.titles.push(title);
|
||||||
tasks.push(fn);
|
tasks.push(fn);
|
||||||
};
|
};
|
||||||
|
(function(arg) {
|
||||||
fs.readdirSync("test/mocha").filter(function(file) {
|
return arg ? [ arg ] : fs.readdirSync("test/mocha").filter(function(file) {
|
||||||
return /\.js$/.test(file);
|
return /\.js$/.test(file);
|
||||||
}).forEach(function(file) {
|
});
|
||||||
|
})(process.argv[2]).forEach(function(file) {
|
||||||
require("./mocha/" + file);
|
require("./mocha/" + file);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -66,12 +68,13 @@ process.nextTick(function run() {
|
|||||||
if (task.length) {
|
if (task.length) {
|
||||||
task.timeout = function(limit) {
|
task.timeout = function(limit) {
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
|
limit += lag;
|
||||||
task.limit = limit;
|
task.limit = limit;
|
||||||
timer = setTimeout(function() {
|
timer = setTimeout(function() {
|
||||||
raise(new Error("Timed out: exceeds " + limit + "ms"));
|
raise(new Error("Timed out: exceeds " + limit + "ms"));
|
||||||
}, limit);
|
}, limit);
|
||||||
};
|
};
|
||||||
task.timeout(task.limit);
|
task.timeout(task.limit - lag);
|
||||||
process.on("uncaughtException", raise);
|
process.on("uncaughtException", raise);
|
||||||
task.call(task, done);
|
task.call(task, done);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -53,6 +53,23 @@ describe("bin/uglifyjs", function() {
|
|||||||
done();
|
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) {
|
it("Should work with --source-map names=true", function(done) {
|
||||||
exec([
|
exec([
|
||||||
uglifyjscmd,
|
uglifyjscmd,
|
||||||
@@ -69,7 +86,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
" q: b",
|
" q: b",
|
||||||
"};",
|
"};",
|
||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,",
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,",
|
||||||
].join("\n")
|
].join("\n");
|
||||||
assert.strictEqual(stdout.slice(0, expected.length), expected);
|
assert.strictEqual(stdout.slice(0, expected.length), expected);
|
||||||
var map = JSON.parse(to_ascii(stdout.slice(expected.length).trim()));
|
var map = JSON.parse(to_ascii(stdout.slice(expected.length).trim()));
|
||||||
assert.deepEqual(map.names, [ "obj", "p", "a", "q", "b" ]);
|
assert.deepEqual(map.names, [ "obj", "p", "a", "q", "b" ]);
|
||||||
@@ -97,7 +114,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
" q: b",
|
" q: b",
|
||||||
"};",
|
"};",
|
||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,",
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,",
|
||||||
].join("\n")
|
].join("\n");
|
||||||
assert.strictEqual(stdout.slice(0, expected.length), expected);
|
assert.strictEqual(stdout.slice(0, expected.length), expected);
|
||||||
var map = JSON.parse(to_ascii(stdout.slice(expected.length).trim()));
|
var map = JSON.parse(to_ascii(stdout.slice(expected.length).trim()));
|
||||||
assert.deepEqual(map.names, []);
|
assert.deepEqual(map.names, []);
|
||||||
@@ -126,7 +143,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, [
|
assert.strictEqual(stdout, [
|
||||||
"var bar=function(){function foo(bar){return bar}return foo}();",
|
"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"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
@@ -313,7 +330,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, [
|
assert.strictEqual(stdout, [
|
||||||
"var bar=function(){function foo(bar){return bar}return foo}();",
|
"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"));
|
].join("\n"));
|
||||||
var stderrLines = stderr.split("\n");
|
var stderrLines = stderr.split("\n");
|
||||||
@@ -333,7 +350,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, [
|
assert.strictEqual(stdout, [
|
||||||
"var Foo=function Foo(){console.log(1+2)};new Foo;var bar=function(){function foo(bar){return bar}return foo}();",
|
"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"));
|
].join("\n"));
|
||||||
var stderrLines = stderr.split("\n");
|
var stderrLines = stderr.split("\n");
|
||||||
@@ -774,7 +791,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, [
|
assert.strictEqual(stdout, [
|
||||||
'"use strict";var foo=function foo(x){return"foo "+x};console.log(foo("bar"));',
|
'"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"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
@@ -797,7 +814,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, [
|
assert.strictEqual(stdout, [
|
||||||
'function foo(){return function(){console.log("PASS")}}foo()();',
|
'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"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
var acorn = require("acorn");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var UglifyJS = require("../node");
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
@@ -25,6 +26,7 @@ describe("export", function() {
|
|||||||
"export { * };",
|
"export { * };",
|
||||||
"export { * as A };",
|
"export { * as A };",
|
||||||
"export { 42 as A };",
|
"export { 42 as A };",
|
||||||
|
"export { 'A' as B };",
|
||||||
"export { A as B-C };",
|
"export { A as B-C };",
|
||||||
"export { default as A };",
|
"export { default as A };",
|
||||||
].forEach(function(code) {
|
].forEach(function(code) {
|
||||||
@@ -51,8 +53,11 @@ describe("export", function() {
|
|||||||
it("Should reject invalid `export ... from ...` statement syntax", function() {
|
it("Should reject invalid `export ... from ...` statement syntax", function() {
|
||||||
[
|
[
|
||||||
"export from 'path';",
|
"export from 'path';",
|
||||||
|
"export A from 'path';",
|
||||||
"export * from `path`;",
|
"export * from `path`;",
|
||||||
|
"export 'A' from 'path';",
|
||||||
"export A as B from 'path';",
|
"export A as B from 'path';",
|
||||||
|
"export 'A' as B from 'path';",
|
||||||
"export default from 'path';",
|
"export default from 'path';",
|
||||||
"export { A }, B from 'path';",
|
"export { A }, B from 'path';",
|
||||||
"export * as A, B from 'path';",
|
"export * as A, B from 'path';",
|
||||||
@@ -68,4 +73,109 @@ describe("export", function() {
|
|||||||
}, code);
|
}, 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 assert = require("assert");
|
||||||
var UglifyJS = require("../node");
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
@@ -8,15 +9,25 @@ describe("import", function() {
|
|||||||
"import A;",
|
"import A;",
|
||||||
"import {};",
|
"import {};",
|
||||||
"import `path`;",
|
"import `path`;",
|
||||||
|
"{ import 'path'; }",
|
||||||
"import from 'path';",
|
"import from 'path';",
|
||||||
|
"if (0) import 'path';",
|
||||||
"import * from 'path';",
|
"import * from 'path';",
|
||||||
|
"import 'A' from 'path';",
|
||||||
|
"import A-B from 'path';",
|
||||||
"import A as B from 'path';",
|
"import A as B from 'path';",
|
||||||
"import { A }, 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, B from 'path';",
|
||||||
"import * as A, {} from 'path';",
|
"import * as A, {} 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 { 42 as A } from 'path';",
|
||||||
"import { A-B as C } from 'path';",
|
"import { A-B as C } from 'path';",
|
||||||
|
"import { 'A' as 'B' } from 'path';",
|
||||||
].forEach(function(code) {
|
].forEach(function(code) {
|
||||||
assert.throws(function() {
|
assert.throws(function() {
|
||||||
UglifyJS.parse(code);
|
UglifyJS.parse(code);
|
||||||
@@ -25,4 +36,74 @@ describe("import", function() {
|
|||||||
}, code);
|
}, 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"));
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -50,12 +50,10 @@ describe("Number literals", function() {
|
|||||||
"0.000_000_004_2e+1_0-0B101_010+0x2_A-0o5_2+4_2",
|
"0.000_000_004_2e+1_0-0B101_010+0x2_A-0o5_2+4_2",
|
||||||
].forEach(function(code) {
|
].forEach(function(code) {
|
||||||
var result = UglifyJS.minify(code, {
|
var result = UglifyJS.minify(code, {
|
||||||
compress: {
|
|
||||||
expression: true,
|
expression: true,
|
||||||
},
|
|
||||||
});
|
});
|
||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code, "42;");
|
assert.strictEqual(result.code, "42");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should reject invalid use of underscore", function() {
|
it("Should reject invalid use of underscore", function() {
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ function source_map(code) {
|
|||||||
function get_map() {
|
function get_map() {
|
||||||
return {
|
return {
|
||||||
"version": 3,
|
"version": 3,
|
||||||
"sources": ["index.js"],
|
"sources": [ "index.js" ],
|
||||||
"names": [],
|
"names": [],
|
||||||
"mappings": ";;AAAA,IAAI,MAAM,SAAN,GAAM;AAAA,SAAK,SAAS,CAAd;AAAA,CAAV;AACA,QAAQ,GAAR,CAAY,IAAI,KAAJ,CAAZ",
|
"mappings": ";;AAAA,IAAI,MAAM,SAAN,GAAM;AAAA,SAAK,SAAS,CAAd;AAAA,CAAV;AACA,QAAQ,GAAR,CAAY,IAAI,KAAJ,CAAZ",
|
||||||
"file": "bundle.js",
|
"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: {
|
sourceMap: {
|
||||||
content: sourceMap,
|
content: sourceMap,
|
||||||
includeSources: true,
|
includeSources: true,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
return JSON.parse(result.map);
|
return JSON.parse(result.map);
|
||||||
@@ -112,7 +112,7 @@ describe("sourcemaps", function() {
|
|||||||
});
|
});
|
||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code, "class A{static P=42;set#q(s){}}");
|
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() {
|
it("Should mark array/object literals", function() {
|
||||||
var result = UglifyJS.minify([
|
var result = UglifyJS.minify([
|
||||||
@@ -124,7 +124,7 @@ describe("sourcemaps", function() {
|
|||||||
});
|
});
|
||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code, "({}).wat([]);");
|
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() {
|
it("Should give correct sourceRoot", function() {
|
||||||
var code = "console.log(42);";
|
var code = "console.log(42);";
|
||||||
@@ -135,7 +135,7 @@ describe("sourcemaps", function() {
|
|||||||
});
|
});
|
||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code, code);
|
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() {
|
it("Should produce same source map with DOS or UNIX line endings", function() {
|
||||||
var code = [
|
var code = [
|
||||||
@@ -160,8 +160,8 @@ describe("sourcemaps", function() {
|
|||||||
sourceMap: {
|
sourceMap: {
|
||||||
content: read("test/input/issue-1236/simple.js.map"),
|
content: read("test/input/issue-1236/simple.js.map"),
|
||||||
filename: "simple.min.js",
|
filename: "simple.min.js",
|
||||||
includeSources: true
|
includeSources: true,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
var map = JSON.parse(result.map);
|
var map = JSON.parse(result.map);
|
||||||
@@ -175,8 +175,8 @@ describe("sourcemaps", function() {
|
|||||||
sourceMap: {
|
sourceMap: {
|
||||||
content: "inline",
|
content: "inline",
|
||||||
includeSources: true,
|
includeSources: true,
|
||||||
url: "inline"
|
url: "inline",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code + "\n", read("test/input/issue-520/output.js"));
|
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"), {
|
var result = UglifyJS.minify(read("test/input/issue-1323/sample.js"), {
|
||||||
mangle: false,
|
mangle: false,
|
||||||
sourceMap: {
|
sourceMap: {
|
||||||
content: "inline"
|
content: "inline",
|
||||||
},
|
},
|
||||||
warnings: true,
|
warnings: true,
|
||||||
});
|
});
|
||||||
@@ -206,7 +206,7 @@ describe("sourcemaps", function() {
|
|||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code, [
|
assert.strictEqual(result.code, [
|
||||||
"var Foo=function(){console.log(3)},bar=(new Foo,function(o){return o});",
|
"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"));
|
].join("\n"));
|
||||||
assert.deepEqual(result.warnings, [ "WARN: inline source map not found: 1" ]);
|
assert.deepEqual(result.warnings, [ "WARN: inline source map not found: 1" ]);
|
||||||
});
|
});
|
||||||
@@ -239,8 +239,8 @@ describe("sourcemaps", function() {
|
|||||||
sourceMap: {
|
sourceMap: {
|
||||||
content: "inline",
|
content: "inline",
|
||||||
includeSources: true,
|
includeSources: true,
|
||||||
url: "inline"
|
url: "inline",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code + "\n", read("test/input/issue-3294/output.js"));
|
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;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code, '(function(){console.log("hello")}).call(this);');
|
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() {
|
it("Should not overwrite existing sourcesContent", function() {
|
||||||
var result = UglifyJS.minify({
|
var result = UglifyJS.minify({
|
||||||
@@ -302,7 +302,7 @@ describe("sourcemaps", function() {
|
|||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
var code = result.code;
|
var code = result.code;
|
||||||
assert.strictEqual(code, "var a=function(n){return n};\n" +
|
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() {
|
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; };');
|
var result = UglifyJS.minify('var a = function(foo) { return foo; };');
|
||||||
|
|||||||
@@ -9,19 +9,22 @@ function beautify(ast) {
|
|||||||
var beautified = UglifyJS.minify(ast, {
|
var beautified = UglifyJS.minify(ast, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
|
module: ufuzz.module,
|
||||||
output: {
|
output: {
|
||||||
|
ast: true,
|
||||||
beautify: true,
|
beautify: true,
|
||||||
braces: true,
|
braces: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (beautified.error) return beautified;
|
if (!beautified.error) {
|
||||||
return UglifyJS.minify(beautified.code, {
|
var verify = UglifyJS.minify(beautified.code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
output: {
|
module: ufuzz.module,
|
||||||
ast: true,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
if (verify.error) return verify;
|
||||||
|
}
|
||||||
|
return beautified;
|
||||||
}
|
}
|
||||||
|
|
||||||
function validate(ast) {
|
function validate(ast) {
|
||||||
@@ -35,6 +38,7 @@ function validate(ast) {
|
|||||||
return UglifyJS.minify(ast, {
|
return UglifyJS.minify(ast, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
|
module: ufuzz.module,
|
||||||
output: {
|
output: {
|
||||||
ast: true,
|
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));
|
var ast = UglifyJS.AST_Node.from_mozilla_ast(to_moz(input));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (skip_on_error) return true;
|
if (skip_on_error) return true;
|
||||||
console.log("//=============================================================");
|
console.error("//=============================================================");
|
||||||
console.log("//", description, "failed... round", round);
|
console.error("//", description, "failed... round", round);
|
||||||
console.log(e);
|
console.error(e);
|
||||||
console.log("// original code");
|
console.error("// original code");
|
||||||
if (beautified === true) console.log("// (beautified)");
|
if (beautified === true) console.error("// (beautified)");
|
||||||
console.log(input.code);
|
console.error(input.code);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var transformed = validate(ast);
|
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;
|
if (!test(beautified, to_moz, description, skip_on_error, true)) return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log("//=============================================================");
|
console.error("//=============================================================");
|
||||||
console.log("// !!!!!! Failed... round", round);
|
console.error("// !!!!!! Failed... round", round);
|
||||||
console.log("// original code");
|
console.error("// original code");
|
||||||
if (beautified.error) {
|
if (beautified.error) {
|
||||||
console.log("// !!! beautify failed !!!");
|
console.error("// !!! beautify failed !!!");
|
||||||
console.log(beautified.error.stack);
|
console.error(beautified.error.stack);
|
||||||
} else if (beautified === true) {
|
} else if (beautified === true) {
|
||||||
console.log("// (beautified)");
|
console.error("// (beautified)");
|
||||||
}
|
}
|
||||||
console.log(input.raw);
|
console.error(input.raw);
|
||||||
console.log();
|
console.error();
|
||||||
console.log();
|
console.error();
|
||||||
console.log("//-------------------------------------------------------------");
|
console.error("//-------------------------------------------------------------");
|
||||||
console.log("//", description);
|
console.error("//", description);
|
||||||
if (transformed.error) {
|
if (transformed.error) {
|
||||||
console.log(transformed.error.stack);
|
console.error(transformed.error.stack);
|
||||||
} else {
|
} else {
|
||||||
beautified = beautify(transformed.ast);
|
beautified = beautify(transformed.ast);
|
||||||
if (beautified.error) {
|
if (beautified.error) {
|
||||||
console.log("// !!! beautify failed !!!");
|
console.error("// !!! beautify failed !!!");
|
||||||
console.log(beautified.error.stack);
|
console.error(beautified.error.stack);
|
||||||
console.log(transformed.code);
|
console.error(transformed.code);
|
||||||
} else {
|
} else {
|
||||||
console.log("// (beautified)");
|
console.error("// (beautified)");
|
||||||
console.log(beautified.code);
|
console.error(beautified.code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log("!!!!!! Failed... round", round);
|
console.error("!!!!!! Failed... round", round);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -115,9 +119,29 @@ for (var round = 1; round <= num_iterations; round++) {
|
|||||||
var code = ufuzz.createTopLevelCode();
|
var code = ufuzz.createTopLevelCode();
|
||||||
minify_options.forEach(function(options) {
|
minify_options.forEach(function(options) {
|
||||||
var ok = true;
|
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,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
|
module: ufuzz.module,
|
||||||
output: {
|
output: {
|
||||||
ast: true,
|
ast: true,
|
||||||
},
|
},
|
||||||
@@ -125,11 +149,27 @@ for (var round = 1; round <= num_iterations; round++) {
|
|||||||
input.raw = options ? input.code : code;
|
input.raw = options ? input.code : code;
|
||||||
if (input.error) {
|
if (input.error) {
|
||||||
ok = false;
|
ok = false;
|
||||||
console.log("//=============================================================");
|
console.error("//=============================================================");
|
||||||
console.log("// minify() failed... round", round);
|
console.error("// parse() failed... round", round);
|
||||||
console.log(input.error);
|
console.error("// original code");
|
||||||
console.log("// original code");
|
console.error(code);
|
||||||
console.log(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) {
|
if (ok) ok = test(input, function(input) {
|
||||||
return input.ast.to_mozilla_ast();
|
return input.ast.to_mozilla_ast();
|
||||||
@@ -141,7 +181,10 @@ for (var round = 1; round <= num_iterations; round++) {
|
|||||||
sourceType: "module",
|
sourceType: "module",
|
||||||
});
|
});
|
||||||
}, "acorn.parse()", !ufuzz.verbose);
|
}, "acorn.parse()", !ufuzz.verbose);
|
||||||
if (!ok) process.exit(1);
|
if (!ok && isFinite(num_iterations)) {
|
||||||
|
console.log();
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
console.log();
|
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;
|
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) {
|
else if (node instanceof U.AST_Binary) {
|
||||||
var permute = ((node.start._permute += step) * steps | 0) % 4;
|
var permute = ((node.start._permute += step) * steps | 0) % 4;
|
||||||
var expr = [
|
var expr = [
|
||||||
@@ -241,23 +246,6 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return node.name;
|
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) {
|
else if (node instanceof U.AST_Defun) {
|
||||||
switch (((node.start._permute += step) * steps | 0) % 2) {
|
switch (((node.start._permute += step) * steps | 0) % 2) {
|
||||||
case 0:
|
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) {
|
else if (node instanceof U.AST_DWLoop) {
|
||||||
var expr = [
|
var expr = [
|
||||||
node.condition,
|
node.condition,
|
||||||
@@ -296,6 +301,16 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
return to_statement(expr);
|
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) {
|
else if (node instanceof U.AST_Finally) {
|
||||||
// drop finally block
|
// drop finally block
|
||||||
node.start._permute++;
|
node.start._permute++;
|
||||||
@@ -351,6 +366,15 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
return to_statement(expr);
|
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) {
|
else if (node instanceof U.AST_Object) {
|
||||||
// first property's value
|
// first property's value
|
||||||
var expr = node.properties[0];
|
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);
|
return to_statement(node.definitions[0].value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (node instanceof U.AST_LabeledStatement) {
|
else if (node instanceof U.AST_VarDef) {
|
||||||
if (node.body instanceof U.AST_Statement
|
if (node.value && !(parent instanceof U.AST_Const)) {
|
||||||
&& !has_loopcontrol(node.body, node.body, node)) {
|
node.start._permute++;
|
||||||
// replace labelled statement with its non-labelled body
|
|
||||||
node.start._permute = REPLACEMENTS.length;
|
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return node.body;
|
return new U.AST_VarDef({
|
||||||
|
name: node.name,
|
||||||
|
start: {},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -778,9 +803,9 @@ function compare_run_code(code, minify_options, result_cache, max_timeout) {
|
|||||||
function run(code, timeout) {
|
function run(code, timeout) {
|
||||||
if (minify_options.module) code = [
|
if (minify_options.module) code = [
|
||||||
'"use strict";',
|
'"use strict";',
|
||||||
"(async function(){",
|
"(async()=>{",
|
||||||
code,
|
code,
|
||||||
"})();"
|
'})().catch(e=>process.on("exit",()=>{throw e}));',
|
||||||
].join("\n");
|
].join("\n");
|
||||||
return run_code(code, toplevel, result_cache, timeout);
|
return run_code(code, toplevel, result_cache, timeout);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ EOF
|
|||||||
}
|
}
|
||||||
if [ $NATIVE ]; then unset -f timeout; fi
|
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
|
rm -rf ~/.nvs
|
||||||
done
|
done
|
||||||
while ! timeout 60 bash -c ". ~/.nvs/nvs.sh add $NODE && nvs use $NODE"; do
|
while ! timeout 60 bash -c ". ~/.nvs/nvs.sh add $NODE && nvs use $NODE"; do
|
||||||
|
|||||||
@@ -371,9 +371,16 @@ var in_class = 0;
|
|||||||
var called = Object.create(null);
|
var called = Object.create(null);
|
||||||
var labels = 10000;
|
var labels = 10000;
|
||||||
|
|
||||||
function rng(max) {
|
function rng(limit) {
|
||||||
var r = randomBytes(2).readUInt16LE(0) / 65536;
|
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() {
|
function strictMode() {
|
||||||
@@ -425,7 +432,7 @@ function createTopLevelCode() {
|
|||||||
if (rng(2)) {
|
if (rng(2)) {
|
||||||
s.push(createStatements(3, MAX_GENERATION_RECURSION_DEPTH, CANNOT_THROW, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, 0));
|
s.push(createStatements(3, MAX_GENERATION_RECURSION_DEPTH, CANNOT_THROW, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, 0));
|
||||||
} else {
|
} 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)
|
// preceding `null` makes for a cleaner output (empty string still shows up etc)
|
||||||
@@ -438,7 +445,7 @@ function createTopLevelCode() {
|
|||||||
function createFunctions(n, recurmax, allowDefun, canThrow, stmtDepth) {
|
function createFunctions(n, recurmax, allowDefun, canThrow, stmtDepth) {
|
||||||
if (--recurmax < 0) { return ";"; }
|
if (--recurmax < 0) { return ";"; }
|
||||||
var s = "";
|
var s = "";
|
||||||
while (n-- > 0) {
|
for (var i = get_num(n - 1) + 1; --i >= 0;) {
|
||||||
s += createFunction(recurmax, allowDefun, canThrow, stmtDepth) + "\n";
|
s += createFunction(recurmax, allowDefun, canThrow, stmtDepth) + "\n";
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
@@ -455,7 +462,7 @@ function createParams(was_async, was_generator, noDuplicate) {
|
|||||||
if (!generator) generator = was_generator;
|
if (!generator) generator = was_generator;
|
||||||
var len = unique_vars.length;
|
var len = unique_vars.length;
|
||||||
var params = [];
|
var params = [];
|
||||||
for (var n = rng(4); --n >= 0;) {
|
for (var i = get_num(3); --i >= 0;) {
|
||||||
var name = createVarName(MANDATORY);
|
var name = createVarName(MANDATORY);
|
||||||
if (noDuplicate || in_class) unique_vars.push(name);
|
if (noDuplicate || in_class) unique_vars.push(name);
|
||||||
params.push(name);
|
params.push(name);
|
||||||
@@ -470,7 +477,7 @@ function createArgs(recurmax, stmtDepth, canThrow, noTemplate) {
|
|||||||
recurmax--;
|
recurmax--;
|
||||||
if (SUPPORT.template && !noTemplate && rng(20) == 0) return createTemplateLiteral(recurmax, stmtDepth, canThrow);
|
if (SUPPORT.template && !noTemplate && rng(20) == 0) return createTemplateLiteral(recurmax, stmtDepth, canThrow);
|
||||||
var args = [];
|
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 0:
|
||||||
case 1:
|
case 1:
|
||||||
var name = getVarName();
|
var name = getVarName();
|
||||||
@@ -850,7 +857,7 @@ function createFunction(recurmax, allowDefun, canThrow, stmtDepth) {
|
|||||||
s.push(defns());
|
s.push(defns());
|
||||||
if (rng(5) === 0) {
|
if (rng(5) === 0) {
|
||||||
// functions with functions. lower the recursion to prevent a mess.
|
// 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 {
|
} else {
|
||||||
// functions with statements
|
// functions with statements
|
||||||
s.push(_createStatements(3, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth));
|
s.push(_createStatements(3, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth));
|
||||||
@@ -880,9 +887,9 @@ function createFunction(recurmax, allowDefun, canThrow, stmtDepth) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) {
|
function _createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) {
|
||||||
if (--recurmax < 0) { return ";"; }
|
if (--recurmax < 0) return ";";
|
||||||
var s = "";
|
var s = "";
|
||||||
while (--n > 0) {
|
for (var i = get_num(n); --i >= 0;) {
|
||||||
s += createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "\n";
|
s += createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "\n";
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
@@ -963,7 +970,7 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
|||||||
switch (target) {
|
switch (target) {
|
||||||
case STMT_BLOCK:
|
case STMT_BLOCK:
|
||||||
var label = createLabel(canBreak);
|
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:
|
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) : "");
|
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:
|
case STMT_DO_WHILE:
|
||||||
@@ -1076,7 +1083,7 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
|||||||
s += " * as " + createImportAlias();
|
s += " * as " + createImportAlias();
|
||||||
} else {
|
} else {
|
||||||
var names = [];
|
var names = [];
|
||||||
for (var i = rng(4); --i >= 0;) {
|
for (var i = get_num(3); --i >= 0;) {
|
||||||
var name = createImportAlias();
|
var name = createImportAlias();
|
||||||
names.push(rng(2) ? getDotKey() + " as " + name : name);
|
names.push(rng(2) ? getDotKey() + " as " + name : name);
|
||||||
}
|
}
|
||||||
@@ -1184,7 +1191,7 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
|||||||
}
|
}
|
||||||
if (n !== 0) s += [
|
if (n !== 0) s += [
|
||||||
" finally { ",
|
" finally { ",
|
||||||
createStatements(rng(5) + 1, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
createStatements(5, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
||||||
" }",
|
" }",
|
||||||
].join("");
|
].join("");
|
||||||
return s;
|
return s;
|
||||||
@@ -1204,7 +1211,7 @@ function createSwitchParts(recurmax, n, canThrow, canBreak, canContinue, cannotR
|
|||||||
if (hadDefault || rng(5) > 0) {
|
if (hadDefault || rng(5) > 0) {
|
||||||
s.push(
|
s.push(
|
||||||
"case " + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + ":",
|
"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 */",
|
rng(10) > 0 ? " break;" : "/* fall-through */",
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
@@ -1212,7 +1219,7 @@ function createSwitchParts(recurmax, n, canThrow, canBreak, canContinue, cannotR
|
|||||||
hadDefault = true;
|
hadDefault = true;
|
||||||
s.push(
|
s.push(
|
||||||
"default:",
|
"default:",
|
||||||
_createStatements(rng(3) + 1, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
_createStatements(3, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1343,7 +1350,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
"(" + params + "{",
|
"(" + params + "{",
|
||||||
strictMode(),
|
strictMode(),
|
||||||
defns(),
|
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 = "})";
|
suffix = "})";
|
||||||
} else {
|
} else {
|
||||||
@@ -1375,7 +1382,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
s.push(
|
s.push(
|
||||||
"(" + makeFunction(name) + "(){",
|
"(" + makeFunction(name) + "(){",
|
||||||
strictMode(),
|
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)
|
rng(2) ? "})" : "})()" + invokeGenerator(save_generator)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1384,7 +1391,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
s.push(
|
s.push(
|
||||||
"+" + makeFunction(name) + "(){",
|
"+" + makeFunction(name) + "(){",
|
||||||
strictMode(),
|
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)
|
"}()" + invokeGenerator(save_generator)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
@@ -1392,7 +1399,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
s.push(
|
s.push(
|
||||||
"!" + makeFunction(name) + "(){",
|
"!" + makeFunction(name) + "(){",
|
||||||
strictMode(),
|
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)
|
"}()" + invokeGenerator(save_generator)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
@@ -1400,7 +1407,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
s.push(
|
s.push(
|
||||||
"void " + makeFunction(name) + "(){",
|
"void " + makeFunction(name) + "(){",
|
||||||
strictMode(),
|
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)
|
"}()" + invokeGenerator(save_generator)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
@@ -1416,10 +1423,10 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
var add_new_target = SUPPORT.new_target && VALUES.indexOf("new.target") < 0;
|
var add_new_target = SUPPORT.new_target && VALUES.indexOf("new.target") < 0;
|
||||||
if (add_new_target) VALUES.push("new.target");
|
if (add_new_target) VALUES.push("new.target");
|
||||||
s.push(defns());
|
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((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);
|
if (add_new_target) VALUES.splice(VALUES.indexOf("new.target"), 1);
|
||||||
});
|
});
|
||||||
generator = save_generator;
|
generator = save_generator;
|
||||||
@@ -1565,7 +1572,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
function createArrayLiteral(recurmax, stmtDepth, canThrow) {
|
function createArrayLiteral(recurmax, stmtDepth, canThrow) {
|
||||||
recurmax--;
|
recurmax--;
|
||||||
var arr = [];
|
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 0:
|
||||||
case 1:
|
case 1:
|
||||||
var name = getVarName();
|
var name = getVarName();
|
||||||
@@ -1594,7 +1601,7 @@ function createTemplateLiteral(recurmax, stmtDepth, canThrow) {
|
|||||||
recurmax--;
|
recurmax--;
|
||||||
var s = [];
|
var s = [];
|
||||||
addText();
|
addText();
|
||||||
for (var i = rng(6); --i >= 0;) {
|
for (var i = get_num(5); --i >= 0;) {
|
||||||
s.push("${", createExpression(recurmax, COMMA_OK, stmtDepth, canThrow), "}");
|
s.push("${", createExpression(recurmax, COMMA_OK, stmtDepth, canThrow), "}");
|
||||||
addText();
|
addText();
|
||||||
}
|
}
|
||||||
@@ -1749,7 +1756,7 @@ function createObjectFunction(recurmax, stmtDepth, canThrow, internal, isClazz)
|
|||||||
s.push(_createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, stmtDepth));
|
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) + ";");
|
if (internal == "super") s.push("super" + createArgs(recurmax, stmtDepth, canThrow, NO_TEMPLATE) + ";");
|
||||||
allow_this = save_allow;
|
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(rng(2) ? createSuperAssignment(recurmax, stmtDepth, canThrow) : createThisAssignment(recurmax, stmtDepth, canThrow));
|
||||||
}
|
}
|
||||||
s.push(_createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth), "}");
|
s.push(_createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth), "}");
|
||||||
@@ -1768,7 +1775,7 @@ function createObjectLiteral(recurmax, stmtDepth, canThrow) {
|
|||||||
var obj = [ "({" ];
|
var obj = [ "({" ];
|
||||||
var offset = SUPPORT.spread_object ? 0 : SUPPORT.computed_key ? 2 : 4;
|
var offset = SUPPORT.spread_object ? 0 : SUPPORT.computed_key ? 2 : 4;
|
||||||
var has_proto = false;
|
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:
|
case 0:
|
||||||
obj.push("..." + getVarName() + ",");
|
obj.push("..." + getVarName() + ",");
|
||||||
break;
|
break;
|
||||||
@@ -1815,7 +1822,7 @@ function createClassLiteral(recurmax, stmtDepth, canThrow, name) {
|
|||||||
}
|
}
|
||||||
s += " {\n";
|
s += " {\n";
|
||||||
var declared = [];
|
var declared = [];
|
||||||
for (var i = rng(6); --i >= 0;) {
|
for (var i = get_num(5); --i >= 0;) {
|
||||||
var fixed = false;
|
var fixed = false;
|
||||||
if (rng(5) == 0) {
|
if (rng(5) == 0) {
|
||||||
fixed = true;
|
fixed = true;
|
||||||
@@ -1849,7 +1856,7 @@ function createClassLiteral(recurmax, stmtDepth, canThrow, name) {
|
|||||||
generator = false;
|
generator = false;
|
||||||
s += [
|
s += [
|
||||||
"{ ",
|
"{ ",
|
||||||
createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, stmtDepth),
|
createStatements(5, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, stmtDepth),
|
||||||
" }\n",
|
" }\n",
|
||||||
].join("");
|
].join("");
|
||||||
generator = save_generator;
|
generator = save_generator;
|
||||||
@@ -2095,7 +2102,11 @@ function createVarName(maybe, dontStore) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (require.main !== module) {
|
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.num_iterations = num_iterations;
|
||||||
exports.verbose = verbose;
|
exports.verbose = verbose;
|
||||||
return;
|
return;
|
||||||
@@ -2104,9 +2115,9 @@ if (require.main !== module) {
|
|||||||
function run_code(code, toplevel, timeout) {
|
function run_code(code, toplevel, timeout) {
|
||||||
if (async && has_await) code = [
|
if (async && has_await) code = [
|
||||||
'"use strict";',
|
'"use strict";',
|
||||||
"(async function(){",
|
"(async()=>{",
|
||||||
code,
|
code,
|
||||||
"})();"
|
'})().catch(e=>process.on("exit",()=>{throw e}));',
|
||||||
].join("\n");
|
].join("\n");
|
||||||
return sandbox.run_code(sandbox.patch_module_statements(code), toplevel, timeout);
|
return sandbox.run_code(sandbox.patch_module_statements(code), toplevel, timeout);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user