Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
860aa9531b | ||
|
|
2547542873 | ||
|
|
3f8f0e246e | ||
|
|
12227ebbb0 | ||
|
|
1b4bd7082b | ||
|
|
0b6c185818 | ||
|
|
bfd0ac7f4b | ||
|
|
1a8f2ecc65 | ||
|
|
dc9e1ff0b1 | ||
|
|
ea10498902 | ||
|
|
69636dad69 | ||
|
|
3ee1b0d00d | ||
|
|
1e3ca4c6f7 | ||
|
|
839f4361f4 | ||
|
|
ae5c3ee8a1 | ||
|
|
77f7ae5ba2 | ||
|
|
2d0f8bcff5 | ||
|
|
f97e107c09 | ||
|
|
e9932e1314 | ||
|
|
eaa84d32df | ||
|
|
6e4aa0326f | ||
|
|
f9a4b36dd1 | ||
|
|
3acb5a329e | ||
|
|
6d94242318 | ||
|
|
bca83cb9df | ||
|
|
a841d45bc3 | ||
|
|
eb93d92357 | ||
|
|
a0250ec923 | ||
|
|
25801627be | ||
|
|
32ae994f88 | ||
|
|
03aec89f60 | ||
|
|
faf0190546 | ||
|
|
c8b0f685ee | ||
|
|
87b99162fb | ||
|
|
940887f20f | ||
|
|
0b2573c3fa | ||
|
|
157521066f | ||
|
|
f766babf5e | ||
|
|
436a29367c | ||
|
|
55418fd460 | ||
|
|
85786889bd | ||
|
|
4b88dfb8d9 | ||
|
|
c3aef23614 | ||
|
|
db94d21980 | ||
|
|
9634a9d1fd | ||
|
|
befb99bd71 | ||
|
|
02eb8baa1c | ||
|
|
c09f63aefb | ||
|
|
fdcc6d3a9c | ||
|
|
4fe2cac35e |
7
.github/workflows/ci.yml
vendored
7
.github/workflows/ci.yml
vendored
@@ -7,14 +7,9 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node: [ '0.8', '0.10', '0.12', '4', '6', '8', '10', '12', '14', latest ]
|
node: [ '0.10', '0.12', '4', '6', '8', '10', '12', '14', '16', latest ]
|
||||||
os: [ ubuntu-latest, windows-latest ]
|
os: [ ubuntu-latest, windows-latest ]
|
||||||
script: [ compress, mocha, release/benchmark, release/jetstream ]
|
script: [ compress, mocha, release/benchmark, release/jetstream ]
|
||||||
exclude:
|
|
||||||
- node: '0.8'
|
|
||||||
script: release/benchmark
|
|
||||||
- node: '0.8'
|
|
||||||
script: release/jetstream
|
|
||||||
name: ${{ matrix.node }} ${{ matrix.os }} ${{ matrix.script }}
|
name: ${{ matrix.node }} ${{ matrix.os }} ${{ matrix.script }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
|
|||||||
11
README.md
11
README.md
@@ -1199,6 +1199,17 @@ To allow for better optimizations, the compiler makes various assumptions:
|
|||||||
- Object properties can be added, removed and modified (not prevented with
|
- Object properties can be added, removed and modified (not prevented with
|
||||||
`Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`,
|
`Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`,
|
||||||
`Object.preventExtensions()` or `Object.seal()`).
|
`Object.preventExtensions()` or `Object.seal()`).
|
||||||
|
- If array destructuring is present, index-like properties in `Array.prototype`
|
||||||
|
have not been overridden:
|
||||||
|
```javascript
|
||||||
|
Object.prototype[0] = 42;
|
||||||
|
var [ a ] = [];
|
||||||
|
var { 0: b } = {};
|
||||||
|
// 42 undefined
|
||||||
|
console.log([][0], a);
|
||||||
|
// 42 42
|
||||||
|
console.log({}[0], b);
|
||||||
|
```
|
||||||
- Earlier versions of JavaScript will throw `SyntaxError` with the following:
|
- Earlier versions of JavaScript will throw `SyntaxError` with the following:
|
||||||
```javascript
|
```javascript
|
||||||
({
|
({
|
||||||
|
|||||||
14
lib/ast.js
14
lib/ast.js
@@ -1289,13 +1289,14 @@ function must_be_expressions(node, prop, allow_spread, allow_hole) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var AST_Call = DEFNODE("Call", "args expression optional pure", {
|
var AST_Call = DEFNODE("Call", "args expression optional pure terminal", {
|
||||||
$documentation: "A function call expression",
|
$documentation: "A function call expression",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
args: "[AST_Node*] array of arguments",
|
args: "[AST_Node*] array of arguments",
|
||||||
expression: "[AST_Node] expression to invoke as function",
|
expression: "[AST_Node] expression to invoke as function",
|
||||||
optional: "[boolean] whether the expression is optional chaining",
|
optional: "[boolean] whether the expression is optional chaining",
|
||||||
pure: "[string/S] marker for side-effect-free call expression",
|
pure: "[string/S] marker for side-effect-free call expression",
|
||||||
|
terminal: "[boolean] whether the chain has ended",
|
||||||
},
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
@@ -1316,6 +1317,7 @@ var AST_New = DEFNODE("New", null, {
|
|||||||
$documentation: "An object instantiation. Derives from a function call since it has exactly the same properties",
|
$documentation: "An object instantiation. Derives from a function call since it has exactly the same properties",
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.optional) throw new Error("optional must be false");
|
if (this.optional) throw new Error("optional must be false");
|
||||||
|
if (this.terminal) throw new Error("terminal must be false");
|
||||||
},
|
},
|
||||||
}, AST_Call);
|
}, AST_Call);
|
||||||
|
|
||||||
@@ -1338,12 +1340,18 @@ var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var AST_PropAccess = DEFNODE("PropAccess", "expression optional property", {
|
function root_expr(prop) {
|
||||||
|
while (prop instanceof AST_PropAccess) prop = prop.expression;
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
var AST_PropAccess = DEFNODE("PropAccess", "expression optional property terminal", {
|
||||||
$documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`",
|
$documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "[AST_Node] the “container” expression",
|
expression: "[AST_Node] the “container” expression",
|
||||||
optional: "[boolean] whether the expression is optional chaining",
|
optional: "[boolean] whether the expression is optional chaining",
|
||||||
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",
|
||||||
},
|
},
|
||||||
get_property: function() {
|
get_property: function() {
|
||||||
var p = this.property;
|
var p = this.property;
|
||||||
@@ -1991,7 +1999,7 @@ TreeWalker.prototype = {
|
|||||||
},
|
},
|
||||||
find_parent: function(type) {
|
find_parent: function(type) {
|
||||||
var stack = this.stack;
|
var stack = this.stack;
|
||||||
for (var i = stack.length; --i >= 0;) {
|
for (var i = stack.length - 1; --i >= 0;) {
|
||||||
var x = stack[i];
|
var x = stack[i];
|
||||||
if (x instanceof type) return x;
|
if (x instanceof type) return x;
|
||||||
}
|
}
|
||||||
|
|||||||
664
lib/compress.js
664
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -556,7 +556,9 @@
|
|||||||
return node;
|
return node;
|
||||||
},
|
},
|
||||||
ChainExpression: function(M) {
|
ChainExpression: function(M) {
|
||||||
return from_moz(M.expression);
|
var node = from_moz(M.expression);
|
||||||
|
node.terminal = true;
|
||||||
|
return node;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -868,7 +870,7 @@
|
|||||||
|
|
||||||
def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) {
|
def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) {
|
||||||
var computed = M instanceof AST_Sub;
|
var computed = M instanceof AST_Sub;
|
||||||
return {
|
var expr = {
|
||||||
type: "MemberExpression",
|
type: "MemberExpression",
|
||||||
object: to_moz(M.expression),
|
object: to_moz(M.expression),
|
||||||
computed: computed,
|
computed: computed,
|
||||||
@@ -878,6 +880,10 @@
|
|||||||
name: M.property,
|
name: M.property,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
return M.terminal ? {
|
||||||
|
type: "ChainExpression",
|
||||||
|
expression: expr,
|
||||||
|
} : expr;
|
||||||
});
|
});
|
||||||
|
|
||||||
def_to_moz(AST_Unary, function To_Moz_Unary(M) {
|
def_to_moz(AST_Unary, function To_Moz_Unary(M) {
|
||||||
|
|||||||
@@ -790,35 +790,26 @@ function OutputStream(options) {
|
|||||||
if (p instanceof AST_Unary) return true;
|
if (p instanceof AST_Unary) return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
function lhs_has_optional(node, output) {
|
function need_chain_parens(node, parent) {
|
||||||
var p = output.parent();
|
if (!node.terminal) return false;
|
||||||
if (p instanceof AST_PropAccess && p.expression === node && is_lhs(p, output.parent(1))) {
|
if (!(parent instanceof AST_Call || parent instanceof AST_PropAccess)) return false;
|
||||||
// ++(foo?.bar).baz
|
return parent.expression === node;
|
||||||
// (foo?.()).bar = baz
|
|
||||||
do {
|
|
||||||
if (node.optional) return true;
|
|
||||||
node = node.expression;
|
|
||||||
} while (node.TYPE == "Call" || node instanceof AST_PropAccess);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PARENS(AST_PropAccess, function(output) {
|
PARENS(AST_PropAccess, function(output) {
|
||||||
var node = this;
|
var node = this;
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
if (p instanceof AST_New) {
|
// i.e. new (foo().bar)
|
||||||
if (p.expression !== node) return false;
|
//
|
||||||
// i.e. new (foo().bar)
|
// if there's one call into this subtree, then we need
|
||||||
//
|
// parens around it too, otherwise the call will be
|
||||||
// if there's one call into this subtree, then we need
|
// interpreted as passing the arguments to the upper New
|
||||||
// parens around it too, otherwise the call will be
|
// expression.
|
||||||
// interpreted as passing the arguments to the upper New
|
if (p instanceof AST_New && p.expression === node && root_expr(node).TYPE == "Call") return true;
|
||||||
// expression.
|
// (foo?.bar)()
|
||||||
do {
|
// (foo?.bar).baz
|
||||||
node = node.expression;
|
// new (foo?.bar)()
|
||||||
} while (node instanceof AST_PropAccess);
|
return need_chain_parens(node, p);
|
||||||
return node.TYPE == "Call";
|
|
||||||
}
|
|
||||||
return lhs_has_optional(node, output);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
PARENS(AST_Call, function(output) {
|
PARENS(AST_Call, function(output) {
|
||||||
@@ -833,7 +824,10 @@ function OutputStream(options) {
|
|||||||
var g = output.parent(1);
|
var g = output.parent(1);
|
||||||
if (g instanceof AST_Assign && g.left === p) return true;
|
if (g instanceof AST_Assign && g.left === p) return true;
|
||||||
}
|
}
|
||||||
return lhs_has_optional(node, output);
|
// (foo?.())()
|
||||||
|
// (foo?.()).bar
|
||||||
|
// new (foo?.())()
|
||||||
|
return need_chain_parens(node, p);
|
||||||
});
|
});
|
||||||
|
|
||||||
PARENS(AST_New, function(output) {
|
PARENS(AST_New, function(output) {
|
||||||
@@ -1158,8 +1152,9 @@ function OutputStream(options) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
function print_arrow(self, output) {
|
function print_arrow(self, output) {
|
||||||
if (self.argnames.length == 1 && self.argnames[0] instanceof AST_SymbolFunarg && !self.rest) {
|
var argname = self.argnames.length == 1 && !self.rest && self.argnames[0];
|
||||||
self.argnames[0].print(output);
|
if (argname instanceof AST_SymbolFunarg && argname.name != "yield") {
|
||||||
|
argname.print(output);
|
||||||
} else {
|
} else {
|
||||||
print_funargs(self, output);
|
print_funargs(self, output);
|
||||||
}
|
}
|
||||||
|
|||||||
153
lib/parse.js
153
lib/parse.js
@@ -44,10 +44,10 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var KEYWORDS = "break case catch class const continue debugger default delete do else extends finally for function if in instanceof let new return switch throw try typeof var void while with";
|
var KEYWORDS = "break case catch class const continue debugger default delete do else extends finally for function if in instanceof new return switch throw try typeof var void while with";
|
||||||
var KEYWORDS_ATOM = "false null true";
|
var KEYWORDS_ATOM = "false null true";
|
||||||
var RESERVED_WORDS = [
|
var RESERVED_WORDS = [
|
||||||
"abstract async await boolean byte char double enum export final float goto implements import int interface long native package private protected public short static super synchronized this throws transient volatile yield",
|
"abstract async await boolean byte char double enum export final float goto implements import int interface let long native package private protected public short static super synchronized this throws transient volatile yield",
|
||||||
KEYWORDS_ATOM,
|
KEYWORDS_ATOM,
|
||||||
KEYWORDS,
|
KEYWORDS,
|
||||||
].join(" ");
|
].join(" ");
|
||||||
@@ -242,10 +242,10 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
read_template : with_eof_error("Unterminated template literal", function(strings) {
|
read_template : with_eof_error("Unterminated template literal", function(strings) {
|
||||||
var s = "";
|
var s = "";
|
||||||
for (;;) {
|
for (;;) {
|
||||||
var ch = next(true, true);
|
var ch = read();
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case "\\":
|
case "\\":
|
||||||
ch += next(true, true);
|
ch += read();
|
||||||
break;
|
break;
|
||||||
case "`":
|
case "`":
|
||||||
strings.push(s);
|
strings.push(s);
|
||||||
@@ -260,6 +260,11 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
}
|
}
|
||||||
s += ch;
|
s += ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function read() {
|
||||||
|
var ch = next(true, true);
|
||||||
|
return ch == "\r" ? "\n" : ch;
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
var prev_was_dot = false;
|
var prev_was_dot = false;
|
||||||
@@ -862,6 +867,15 @@ function parse($TEXT, options) {
|
|||||||
next();
|
next();
|
||||||
return import_();
|
return import_();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case "let":
|
||||||
|
if (is_vardefs()) {
|
||||||
|
next();
|
||||||
|
var node = let_();
|
||||||
|
semicolon();
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "yield":
|
case "yield":
|
||||||
if (S.in_generator) return simple_statement();
|
if (S.in_generator) return simple_statement();
|
||||||
break;
|
break;
|
||||||
@@ -947,12 +961,6 @@ function parse($TEXT, options) {
|
|||||||
next();
|
next();
|
||||||
return if_();
|
return if_();
|
||||||
|
|
||||||
case "let":
|
|
||||||
next();
|
|
||||||
var node = let_();
|
|
||||||
semicolon();
|
|
||||||
return node;
|
|
||||||
|
|
||||||
case "return":
|
case "return":
|
||||||
if (S.in_function == 0 && !options.bare_returns)
|
if (S.in_function == 0 && !options.bare_returns)
|
||||||
croak("'return' outside of function");
|
croak("'return' outside of function");
|
||||||
@@ -1192,7 +1200,7 @@ function parse($TEXT, options) {
|
|||||||
if (await || !is("punc", ";")) {
|
if (await || !is("punc", ";")) {
|
||||||
init = is("keyword", "const")
|
init = is("keyword", "const")
|
||||||
? (next(), const_(true))
|
? (next(), const_(true))
|
||||||
: is("keyword", "let")
|
: is("name", "let") && is_vardefs()
|
||||||
? (next(), let_(true))
|
? (next(), let_(true))
|
||||||
: is("keyword", "var")
|
: is("keyword", "var")
|
||||||
? (next(), var_(true))
|
? (next(), var_(true))
|
||||||
@@ -1308,6 +1316,11 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolFunarg) return node;
|
if (node instanceof AST_SymbolFunarg) return node;
|
||||||
if (node instanceof AST_SymbolRef) return new AST_SymbolFunarg(node);
|
if (node instanceof AST_SymbolRef) return new AST_SymbolFunarg(node);
|
||||||
|
if (node instanceof AST_Yield) return new AST_SymbolFunarg({
|
||||||
|
start: node.start,
|
||||||
|
name: "yield",
|
||||||
|
end: node.end,
|
||||||
|
});
|
||||||
token_error(node.start, "Invalid arrow parameter");
|
token_error(node.start, "Invalid arrow parameter");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1535,12 +1548,18 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var export_decl = embed_tokens(function() {
|
var export_decl = embed_tokens(function() {
|
||||||
if (is("name", "async")) {
|
if (is("name")) switch (S.token.value) {
|
||||||
|
case "async":
|
||||||
next();
|
next();
|
||||||
expect_token("keyword", "function");
|
expect_token("keyword", "function");
|
||||||
if (!is("operator", "*")) return function_(AST_AsyncDefun);
|
if (!is("operator", "*")) return function_(AST_AsyncDefun);
|
||||||
next();
|
next();
|
||||||
return function_(AST_AsyncGeneratorDefun);
|
return function_(AST_AsyncGeneratorDefun);
|
||||||
|
case "let":
|
||||||
|
next();
|
||||||
|
var node = let_();
|
||||||
|
semicolon();
|
||||||
|
return node;
|
||||||
} else if (is("keyword")) switch (S.token.value) {
|
} else if (is("keyword")) switch (S.token.value) {
|
||||||
case "class":
|
case "class":
|
||||||
next();
|
next();
|
||||||
@@ -1555,11 +1574,6 @@ function parse($TEXT, options) {
|
|||||||
if (!is("operator", "*")) return function_(AST_Defun);
|
if (!is("operator", "*")) return function_(AST_Defun);
|
||||||
next();
|
next();
|
||||||
return function_(AST_GeneratorDefun);
|
return function_(AST_GeneratorDefun);
|
||||||
case "let":
|
|
||||||
next();
|
|
||||||
var node = let_();
|
|
||||||
semicolon();
|
|
||||||
return node;
|
|
||||||
case "var":
|
case "var":
|
||||||
next();
|
next();
|
||||||
var node = var_();
|
var node = var_();
|
||||||
@@ -1720,6 +1734,11 @@ function parse($TEXT, options) {
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function is_vardefs() {
|
||||||
|
var token = peek();
|
||||||
|
return is_token(token, "name") || is_token(token, "punc", "[") || is_token(token, "punc", "{");
|
||||||
|
}
|
||||||
|
|
||||||
var const_ = function(no_in) {
|
var const_ = function(no_in) {
|
||||||
return new AST_Const({
|
return new AST_Const({
|
||||||
start : prev(),
|
start : prev(),
|
||||||
@@ -1818,10 +1837,7 @@ function parse($TEXT, options) {
|
|||||||
if (is("punc")) {
|
if (is("punc")) {
|
||||||
switch (start.value) {
|
switch (start.value) {
|
||||||
case "`":
|
case "`":
|
||||||
var tmpl = template(null);
|
return subscripts(template(null), allow_calls);
|
||||||
tmpl.start = start;
|
|
||||||
tmpl.end = prev();
|
|
||||||
return subscripts(tmpl, allow_calls);
|
|
||||||
case "(":
|
case "(":
|
||||||
next();
|
next();
|
||||||
if (is("punc", ")")) {
|
if (is("punc", ")")) {
|
||||||
@@ -2133,7 +2149,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function strict_verify_symbol(sym) {
|
function strict_verify_symbol(sym) {
|
||||||
if (sym.name == "arguments" || sym.name == "eval")
|
if (sym.name == "arguments" || sym.name == "eval" || sym.name == "let")
|
||||||
token_error(sym.start, "Unexpected " + sym.name + " in strict mode");
|
token_error(sym.start, "Unexpected " + sym.name + " in strict mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2230,6 +2246,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function template(tag) {
|
function template(tag) {
|
||||||
|
var start = tag ? tag.start : S.token;
|
||||||
var read = S.input.context().read_template;
|
var read = S.input.context().read_template;
|
||||||
var strings = [];
|
var strings = [];
|
||||||
var expressions = [];
|
var expressions = [];
|
||||||
@@ -2240,58 +2257,60 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
return new AST_Template({
|
return new AST_Template({
|
||||||
|
start: start,
|
||||||
expressions: expressions,
|
expressions: expressions,
|
||||||
strings: strings,
|
strings: strings,
|
||||||
tag: tag,
|
tag: tag,
|
||||||
|
end: prev(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var subscripts = function(expr, allow_calls, optional) {
|
function subscripts(expr, allow_calls) {
|
||||||
var start = expr.start;
|
var start = expr.start;
|
||||||
if (is("punc", "[")) {
|
var optional = null;
|
||||||
next();
|
while (true) {
|
||||||
var prop = expression();
|
if (is("operator", "?") && is_token(peek(), "punc", ".")) {
|
||||||
expect("]");
|
next();
|
||||||
return subscripts(new AST_Sub({
|
next();
|
||||||
start: start,
|
optional = expr;
|
||||||
optional: optional,
|
}
|
||||||
expression: expr,
|
if (is("punc", "[")) {
|
||||||
property: prop,
|
next();
|
||||||
end: prev(),
|
var prop = expression();
|
||||||
}), allow_calls);
|
expect("]");
|
||||||
}
|
expr = new AST_Sub({
|
||||||
if (allow_calls && is("punc", "(")) {
|
start: start,
|
||||||
next();
|
optional: optional === expr,
|
||||||
var call = new AST_Call({
|
expression: expr,
|
||||||
start: start,
|
property: prop,
|
||||||
optional: optional,
|
end: prev(),
|
||||||
expression: expr,
|
});
|
||||||
args: expr_list(")", !options.strict),
|
} else if (allow_calls && is("punc", "(")) {
|
||||||
end: prev(),
|
next();
|
||||||
});
|
expr = new AST_Call({
|
||||||
return subscripts(call, true);
|
start: start,
|
||||||
}
|
optional: optional === expr,
|
||||||
if (optional || is("punc", ".")) {
|
expression: expr,
|
||||||
if (!optional) next();
|
args: expr_list(")", !options.strict),
|
||||||
return subscripts(new AST_Dot({
|
end: prev(),
|
||||||
start: start,
|
});
|
||||||
optional: optional,
|
} else if (optional === expr || is("punc", ".")) {
|
||||||
expression: expr,
|
if (optional !== expr) next();
|
||||||
property: as_name(),
|
expr = new AST_Dot({
|
||||||
end: prev(),
|
start: start,
|
||||||
}), allow_calls);
|
optional: optional === expr,
|
||||||
}
|
expression: expr,
|
||||||
if (is("punc", "`")) {
|
property: as_name(),
|
||||||
var tmpl = template(expr);
|
end: prev(),
|
||||||
tmpl.start = expr.start;
|
});
|
||||||
tmpl.end = prev();
|
} else if (is("punc", "`")) {
|
||||||
return subscripts(tmpl, allow_calls);
|
if (optional) croak("Invalid template on optional chain");
|
||||||
}
|
expr = template(expr);
|
||||||
if (is("operator", "?") && is_token(peek(), "punc", ".")) {
|
} else {
|
||||||
next();
|
break;
|
||||||
next();
|
}
|
||||||
return subscripts(expr, allow_calls, true);
|
|
||||||
}
|
}
|
||||||
|
if (optional) expr.terminal = true;
|
||||||
if (expr instanceof AST_Call && !expr.pure) {
|
if (expr instanceof AST_Call && !expr.pure) {
|
||||||
var start = expr.start;
|
var start = expr.start;
|
||||||
var comments = start.comments_before;
|
var comments = start.comments_before;
|
||||||
@@ -2305,7 +2324,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return expr;
|
return expr;
|
||||||
};
|
}
|
||||||
|
|
||||||
function maybe_unary(no_in) {
|
function maybe_unary(no_in) {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ 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 = props[p];
|
||||||
return value instanceof AST_Node ? value.print_to_string() : value;
|
return value instanceof AST_Node ? value.print_to_string() : 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.14.1",
|
"version": "3.14.4",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -550,6 +550,24 @@ logical_side_effects: {
|
|||||||
node_version: ">=15"
|
node_version: ">=15"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
evaluate_lazy_assignment: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 42;
|
||||||
|
console.log(a &&= "PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=15"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4815_1: {
|
issue_4815_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ inline_await_1_trim: {
|
|||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
void 0;
|
0;
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -453,7 +453,7 @@ object_function: {
|
|||||||
}).f();
|
}).f();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(async function() {
|
(async () => {
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
@@ -571,7 +571,7 @@ drop_async_1: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(function(a) {
|
console.log(function(a) {
|
||||||
void (a *= 7);
|
a *= 7;
|
||||||
return a;
|
return a;
|
||||||
}(6));
|
}(6));
|
||||||
}
|
}
|
||||||
@@ -1774,7 +1774,7 @@ issue_5001: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 0;
|
var a = 0;
|
||||||
void a++;
|
a++;
|
||||||
console.log(a ? "PASS" : "FAIL");
|
console.log(a ? "PASS" : "FAIL");
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -2046,3 +2046,195 @@ issue_5070: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=10"
|
node_version: ">=10"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5157_async_function: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
async function f() {
|
||||||
|
throw "FAIL";
|
||||||
|
}
|
||||||
|
(async function() {
|
||||||
|
try {
|
||||||
|
return await f();
|
||||||
|
} catch (e) {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
})().then(console.log);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
async function f() {
|
||||||
|
throw "FAIL";
|
||||||
|
}
|
||||||
|
(async function() {
|
||||||
|
try {
|
||||||
|
return await f();
|
||||||
|
} catch (e) {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
})().then(console.log);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5157_async_iife: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
try {
|
||||||
|
return await async function() {
|
||||||
|
throw "FAIL";
|
||||||
|
}();
|
||||||
|
} catch (e) {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
})().then(console.log);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
try {
|
||||||
|
return await async function() {
|
||||||
|
throw "FAIL";
|
||||||
|
}();
|
||||||
|
} catch (e) {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
})().then(console.log);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5157_promise: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var p = new Promise(function(resolve, reject) {
|
||||||
|
reject("FAIL");
|
||||||
|
});
|
||||||
|
(async function() {
|
||||||
|
try {
|
||||||
|
return await p;
|
||||||
|
} catch (e) {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
})().then(console.log);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var p = new Promise(function(resolve, reject) {
|
||||||
|
reject("FAIL");
|
||||||
|
});
|
||||||
|
(async function() {
|
||||||
|
try {
|
||||||
|
return await p;
|
||||||
|
} catch (e) {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
})().then(console.log);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5159_1: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
try {
|
||||||
|
throw "foo";
|
||||||
|
} catch (e) {
|
||||||
|
return await "bar";
|
||||||
|
} finally {
|
||||||
|
console.log("baz");
|
||||||
|
}
|
||||||
|
})().catch(console.log).then(console.log);
|
||||||
|
console.log("moo");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
try {
|
||||||
|
throw "foo";
|
||||||
|
} catch (e) {
|
||||||
|
return await "bar";
|
||||||
|
} finally {
|
||||||
|
console.log("baz");
|
||||||
|
}
|
||||||
|
})().catch(console.log).then(console.log);
|
||||||
|
console.log("moo");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"moo",
|
||||||
|
"baz",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5159_2: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
try {
|
||||||
|
throw "foo";
|
||||||
|
} catch (e) {
|
||||||
|
return await "bar";
|
||||||
|
}
|
||||||
|
})().catch(console.log).then(console.log);
|
||||||
|
console.log("baz");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
try {
|
||||||
|
throw "foo";
|
||||||
|
} catch (e) {
|
||||||
|
return "bar";
|
||||||
|
}
|
||||||
|
})().catch(console.log).then(console.log);
|
||||||
|
console.log("baz");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"baz",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5177: {
|
||||||
|
options = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
return {
|
||||||
|
p(await) {},
|
||||||
|
}.p;
|
||||||
|
})().then(function(a) {
|
||||||
|
console.log(typeof a);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
return {
|
||||||
|
p(await) {},
|
||||||
|
}.p;
|
||||||
|
})().then(function(a) {
|
||||||
|
console.log(typeof a);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|||||||
@@ -2066,3 +2066,34 @@ issue_5082_2: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=12"
|
node_version: ">=12"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5142: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
merge_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b;
|
||||||
|
if (++a)
|
||||||
|
new class {
|
||||||
|
p = b = null;
|
||||||
|
constructor(c) {
|
||||||
|
console.log(c ? "FAIL" : "PASS");
|
||||||
|
}
|
||||||
|
}(b, a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b;
|
||||||
|
if (++a)
|
||||||
|
new class {
|
||||||
|
p = b = null;
|
||||||
|
constructor(c) {
|
||||||
|
console.log(c ? "FAIL" : "PASS");
|
||||||
|
}
|
||||||
|
}(b, 1);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=12"
|
||||||
|
}
|
||||||
|
|||||||
@@ -9253,13 +9253,13 @@ issue_4920_2: {
|
|||||||
console.log(b);
|
console.log(b);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var o = {
|
var o;
|
||||||
|
var a = "PASS", b;
|
||||||
|
({
|
||||||
get PASS() {
|
get PASS() {
|
||||||
a = "FAIL";
|
a = "FAIL";
|
||||||
},
|
},
|
||||||
};
|
})[b = a];
|
||||||
var a = "PASS", b;
|
|
||||||
o[b = a];
|
|
||||||
console.log(b);
|
console.log(b);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -9283,16 +9283,47 @@ issue_4920_3: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var log = console.log;
|
var log = console.log;
|
||||||
var o = {
|
var o;
|
||||||
|
var a = "PASS", b;
|
||||||
|
({
|
||||||
get PASS() {
|
get PASS() {
|
||||||
a = "FAIL";
|
a = "FAIL";
|
||||||
},
|
},
|
||||||
|
})[b = a];
|
||||||
|
log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4920_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = console.log;
|
||||||
|
var o = {
|
||||||
|
get [(a = "FAIL 1", "PASS")]() {
|
||||||
|
a = "FAIL 2";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var a = "PASS", b;
|
||||||
|
o[b = a];
|
||||||
|
log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log;
|
||||||
|
var o = {
|
||||||
|
get [(a = "FAIL 1", "PASS")]() {
|
||||||
|
a = "FAIL 2";
|
||||||
|
},
|
||||||
};
|
};
|
||||||
var a = "PASS", b;
|
var a = "PASS", b;
|
||||||
o[b = a];
|
o[b = a];
|
||||||
log(b);
|
log(b);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_4935: {
|
issue_4935: {
|
||||||
@@ -9412,3 +9443,126 @@ issue_4977_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS PASS"
|
expect_stdout: "PASS PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5112_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
if (console + (a = "PASS", ""))
|
||||||
|
return "FAIL 1";
|
||||||
|
a.p;
|
||||||
|
} catch (e) {}
|
||||||
|
} finally {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}("FAIL 2"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
if (console + (a = "PASS", ""))
|
||||||
|
return "FAIL 1";
|
||||||
|
a.p;
|
||||||
|
} catch (e) {}
|
||||||
|
} finally {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}("FAIL 2"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5112_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
try {
|
||||||
|
return function() {
|
||||||
|
try {
|
||||||
|
if (console + (a = "PASS", ""))
|
||||||
|
return "FAIL 1";
|
||||||
|
a.p;
|
||||||
|
} catch (e) {}
|
||||||
|
}();
|
||||||
|
} finally {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}("FAIL 2"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
try {
|
||||||
|
return function() {
|
||||||
|
try {
|
||||||
|
if (console + (a = "PASS", ""))
|
||||||
|
return "FAIL 1";
|
||||||
|
a.p;
|
||||||
|
} catch (e) {}
|
||||||
|
}();
|
||||||
|
} finally {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}("FAIL 2"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5182: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_props: true,
|
||||||
|
inline: true,
|
||||||
|
merge_vars: true,
|
||||||
|
passes: 4,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var con = console;
|
||||||
|
global.log = con.log;
|
||||||
|
var jump = function(x) {
|
||||||
|
console.log("JUMP:", x * 10);
|
||||||
|
return x + x;
|
||||||
|
};
|
||||||
|
var jump2 = jump;
|
||||||
|
var run = function(x) {
|
||||||
|
console.log("RUN:", x * -10);
|
||||||
|
return x * x;
|
||||||
|
};
|
||||||
|
var run2 = run;
|
||||||
|
var bar = (x, y) => {
|
||||||
|
console.log("BAR:", x + y);
|
||||||
|
return x - y;
|
||||||
|
};
|
||||||
|
var bar2 = bar;
|
||||||
|
var obj = {
|
||||||
|
foo: bar2,
|
||||||
|
go: run2,
|
||||||
|
not_used: jump2,
|
||||||
|
};
|
||||||
|
console.log(obj.foo(1, 2), global.log("PASS"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var con = console;
|
||||||
|
global.log = con.log,
|
||||||
|
console.log((console.log("BAR:", 3), -1), global.log("PASS"));
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"BAR: 3",
|
||||||
|
"PASS",
|
||||||
|
"-1 undefined",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -289,3 +289,18 @@ issue_3689: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "00"
|
expect_stdout: "00"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5145: {
|
||||||
|
options = {
|
||||||
|
strings: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [];
|
||||||
|
console.log("" + a + ((a[0] = 4) + "2"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = [];
|
||||||
|
console.log("" + a + (a[0] = 4) + "2");
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1633,3 +1633,39 @@ issue_5030: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=0.12"
|
node_version: ">=0.12"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5106_1: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof function(a) {
|
||||||
|
return a = arguments;
|
||||||
|
}("FAIL")[0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof function(a) {
|
||||||
|
return a = arguments;
|
||||||
|
}("FAIL")[0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "object"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5106_2: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
console.log(function(a) {
|
||||||
|
return a = arguments;
|
||||||
|
}("PASS")[0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
console.log(function(a) {
|
||||||
|
return arguments;
|
||||||
|
}("PASS")[0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -568,6 +568,20 @@ retain_empty_iife: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drop_new_function: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new function(a = console.log("PASS")) {}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
void console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
retain_fargs: {
|
retain_fargs: {
|
||||||
options = {
|
options = {
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -1890,3 +1904,56 @@ issue_5065: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5138_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, b = a = "FAIL") {
|
||||||
|
return a;
|
||||||
|
}() && "PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a, b = a = "FAIL") {
|
||||||
|
return a;
|
||||||
|
}() && "PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5138_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, b = a = "FAIL 1") {
|
||||||
|
return a;
|
||||||
|
}(null, "FAIL 2") || "PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log((null, "PASS"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5192: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
ie: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function a(a, [] = a = "PASS") {
|
||||||
|
console.log(a);
|
||||||
|
})("FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function a(a, [] = a = "PASS") {
|
||||||
|
console.log(a);
|
||||||
|
})("FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1581,6 +1581,75 @@ hoist_vars: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
singleton_1: {
|
||||||
|
options = {
|
||||||
|
pure_getters: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var [ a ] = "P", b, o = {};
|
||||||
|
[ { 1: o.p } ] = [ "FAIL" ];
|
||||||
|
({ foo: [ o.q ] } = { foo: "S" });
|
||||||
|
[ b = "S" ] = [];
|
||||||
|
console.log(a + o.p + o.q + b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b, a = "P"[0], o = {};
|
||||||
|
o.p = [ "FAIL"["1"] ][0];
|
||||||
|
o.q = { foo: "S"[0] }["foo"];
|
||||||
|
[ b = "S" ] = [];
|
||||||
|
console.log(a + o.p + o.q + b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
singleton_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
passes: 2,
|
||||||
|
pure_getters: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var [ a ] = "P", b, o = {};
|
||||||
|
[ { 1: o.p } ] = [ "FAIL" ];
|
||||||
|
({ foo: [ o.q ] } = { foo: "S" });
|
||||||
|
[ b = "S" ] = [];
|
||||||
|
console.log(a + o.p + o.q + b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b, a = "P", o = {};
|
||||||
|
o.p = "A";
|
||||||
|
o.q = "S";
|
||||||
|
[ b = "S" ] = [];
|
||||||
|
console.log(a + o.p + o.q + b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
singleton_side_effects: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
[ 42[console.log("foo")] ] = [ console.log("bar") ];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
[ 42[console.log("foo")] ] = [ console.log("bar") ];
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"bar",
|
||||||
|
"foo",
|
||||||
|
]
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4280: {
|
issue_4280: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -2127,7 +2196,7 @@ issue_4372_2: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a;
|
var a;
|
||||||
[ a ] = [ "PASS", "FAIL" ];
|
[ a ] = a = [ "PASS", "FAIL" ];
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -3057,3 +3126,243 @@ issue_5087_2: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5114_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function({}, a) {})(42);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
[ {} ] = [ 42 ],
|
||||||
|
void 0;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5114_2: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function f([], a) {
|
||||||
|
f.length;
|
||||||
|
})([]);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
0;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5114_3: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function f(a, {}) {
|
||||||
|
f.length;
|
||||||
|
})(null, 42);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
0;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5153_array_assign: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function*() {
|
||||||
|
yield b;
|
||||||
|
}(), b;
|
||||||
|
[ b ] = b = a;
|
||||||
|
console.log(a === b ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function*() {
|
||||||
|
yield b;
|
||||||
|
}(), b;
|
||||||
|
[ b ] = b = a;
|
||||||
|
console.log(a === b ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5153_array_var: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function*() {
|
||||||
|
yield b;
|
||||||
|
}(), [ b ] = b = a;
|
||||||
|
console.log(a === b ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function*() {
|
||||||
|
yield b;
|
||||||
|
}(), [ b ] = b = a;
|
||||||
|
console.log(a === b ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5153_object_assign: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = {
|
||||||
|
get p() {
|
||||||
|
return b;
|
||||||
|
},
|
||||||
|
}, b;
|
||||||
|
({
|
||||||
|
p: b
|
||||||
|
} = b = a);
|
||||||
|
console.log(a === b ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = {
|
||||||
|
get p() {
|
||||||
|
return b;
|
||||||
|
},
|
||||||
|
}, b;
|
||||||
|
({
|
||||||
|
p: b
|
||||||
|
} = b = a);
|
||||||
|
console.log(a === b ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5153_object_var: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = {
|
||||||
|
get p() {
|
||||||
|
return b;
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
p: b
|
||||||
|
} = b = a;
|
||||||
|
console.log(a === b ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = {
|
||||||
|
get p() {
|
||||||
|
return b;
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
p: b
|
||||||
|
} = b = a;
|
||||||
|
console.log(a === b ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5168: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function a({
|
||||||
|
[console.log(typeof function() {
|
||||||
|
++a;
|
||||||
|
return a;
|
||||||
|
}())]: b,
|
||||||
|
}) {
|
||||||
|
var a;
|
||||||
|
})({});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function a({
|
||||||
|
[console.log(typeof function() {
|
||||||
|
++a;
|
||||||
|
return a;
|
||||||
|
}())]: b,
|
||||||
|
}) {
|
||||||
|
var a;
|
||||||
|
})({});
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5189_1: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 42;
|
||||||
|
[ a.p ] = a = "PASS";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
[ a.p ] = a = "PASS";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5189_2: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 42;
|
||||||
|
({ p: a.q } = a = "PASS");
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
({ p: a.q } = a = "PASS");
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1557,9 +1557,9 @@ issue_2665: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 1;
|
var a = 1;
|
||||||
!function g() {
|
(function g() {
|
||||||
a-- && g();
|
a-- && g();
|
||||||
}();
|
})();
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_stdout: "-1"
|
expect_stdout: "-1"
|
||||||
@@ -2916,7 +2916,7 @@ issue_4133: {
|
|||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var b = 1;
|
var a = 1;
|
||||||
console.log(0);
|
console.log(0);
|
||||||
}
|
}
|
||||||
expect_stdout: "0"
|
expect_stdout: "0"
|
||||||
@@ -3062,7 +3062,7 @@ issue_4184: {
|
|||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_4235: {
|
issue_4235_1: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -3081,13 +3081,37 @@ issue_4235: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
void function() {
|
void function() {
|
||||||
var f;
|
var f = console.log(f);
|
||||||
console.log(f);
|
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4235_2: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
varify: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
{
|
||||||
|
const f = 0;
|
||||||
|
}
|
||||||
|
(function f() {
|
||||||
|
var f = console.log(f);
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4404: {
|
issue_4404: {
|
||||||
options = {
|
options = {
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
@@ -3379,7 +3403,7 @@ issue_4834: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
try {
|
try {
|
||||||
void b.p;
|
b.p;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,8 +99,8 @@ issue_4664: {
|
|||||||
expect: {
|
expect: {
|
||||||
(function f() {
|
(function f() {
|
||||||
new function(a) {
|
new function(a) {
|
||||||
console.log(typeof f, 1073741824, typeof this);
|
console.log(typeof f, a, typeof this);
|
||||||
}(A = 0);
|
}((A = 0, 2 ** 30));
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect_stdout: "function 1073741824 object"
|
expect_stdout: "function 1073741824 object"
|
||||||
|
|||||||
@@ -1171,11 +1171,11 @@ issue_2620_4: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var c = "FAIL";
|
var c = "FAIL";
|
||||||
!function() {
|
(function() {
|
||||||
switch (NaN) {
|
switch (NaN) {
|
||||||
case void (c = "PASS"):
|
case void (c = "PASS"):
|
||||||
}
|
}
|
||||||
}();
|
})();
|
||||||
console.log(c);
|
console.log(c);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -4857,8 +4857,9 @@ issue_4155: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(function() {
|
(function() {
|
||||||
void console.log(b);
|
var a;
|
||||||
var b = function() {};
|
void console.log(a);
|
||||||
|
function b() {}
|
||||||
b && console.log(typeof b);
|
b && console.log(typeof b);
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
@@ -6565,3 +6566,139 @@ issue_5098: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shorter_without_void: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
function f(b) {
|
||||||
|
a = b;
|
||||||
|
}
|
||||||
|
f("foo");
|
||||||
|
console.log(a) || f("bar");
|
||||||
|
console.log(a, f("baz"));
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
function f(b) {
|
||||||
|
a = b;
|
||||||
|
}
|
||||||
|
a = "foo";
|
||||||
|
console.log(a) || (a = "bar");
|
||||||
|
console.log(a, f("baz"));
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar undefined",
|
||||||
|
"baz",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5120: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function f() {
|
||||||
|
function g() {
|
||||||
|
f || g();
|
||||||
|
}
|
||||||
|
g();
|
||||||
|
return f.valueOf();
|
||||||
|
};
|
||||||
|
console.log(a() === a ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a() {
|
||||||
|
(function g() {
|
||||||
|
a || g();
|
||||||
|
})();
|
||||||
|
return a.valueOf();
|
||||||
|
}
|
||||||
|
console.log(a() === a ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5140: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = 42;
|
||||||
|
function f(b) {
|
||||||
|
return b >> 0;
|
||||||
|
}
|
||||||
|
var a = f(42 in []);
|
||||||
|
console.log(f(A));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(b) {
|
||||||
|
return b >> 0;
|
||||||
|
}
|
||||||
|
A = 42;
|
||||||
|
console.log(A >> 0);
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5173_1: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, b) {
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
f([ A = 42, [] + "" || (A = f) ]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, b) {
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
f([ A = 42, [] + "" || (A = f) ]);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5173_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, b) {
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
f([ A = 42, [] + "" || (A = f) ]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, b) {
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
f(A = [] + "" ? 42 : f);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|||||||
@@ -217,7 +217,8 @@ name_collision_1: {
|
|||||||
var obj_foo = 1;
|
var obj_foo = 1;
|
||||||
var obj_bar = 2;
|
var obj_bar = 2;
|
||||||
function f() {
|
function f() {
|
||||||
var obj_foo$0 = 3,
|
var obj,
|
||||||
|
obj_foo$0 = 3,
|
||||||
obj_bar = 4,
|
obj_bar = 4,
|
||||||
obj_b_r = 5,
|
obj_b_r = 5,
|
||||||
obj_b_r$0 = 6,
|
obj_b_r$0 = 6,
|
||||||
@@ -249,7 +250,8 @@ name_collision_2: {
|
|||||||
console.log(o.p === o.p, o["+"](4), o["-"](5), o__$0, o__$1);
|
console.log(o.p === o.p, o["+"](4), o["-"](5), o__$0, o__$1);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var o_p = 1,
|
var o,
|
||||||
|
o_p = 1,
|
||||||
o__ = function(x) {
|
o__ = function(x) {
|
||||||
return x;
|
return x;
|
||||||
},
|
},
|
||||||
@@ -283,7 +285,8 @@ name_collision_3: {
|
|||||||
console.log(o.p === o.p, o["+"](4), o["-"](5));
|
console.log(o.p === o.p, o["+"](4), o["-"](5));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var o_p = 1,
|
var o,
|
||||||
|
o_p = 1,
|
||||||
o__ = function(x) {
|
o__ = function(x) {
|
||||||
return x;
|
return x;
|
||||||
},
|
},
|
||||||
@@ -315,7 +318,7 @@ name_collision_4: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(function() {
|
console.log(function() {
|
||||||
var o_p$0 = 0, o_q = "PASS";
|
var o, o_p$0 = 0, o_q = "PASS";
|
||||||
return function(o_p) {
|
return function(o_p) {
|
||||||
if (!o_p$0) return o_p;
|
if (!o_p$0) return o_p;
|
||||||
}(o_q);
|
}(o_q);
|
||||||
@@ -768,7 +771,7 @@ issue_3046: {
|
|||||||
expect: {
|
expect: {
|
||||||
console.log(function(a) {
|
console.log(function(a) {
|
||||||
do {
|
do {
|
||||||
var b_c = a++;
|
var b, b_c = a++;
|
||||||
} while (b_c && a);
|
} while (b_c && a);
|
||||||
return a;
|
return a;
|
||||||
}(0));
|
}(0));
|
||||||
@@ -931,7 +934,7 @@ issue_3411: {
|
|||||||
expect: {
|
expect: {
|
||||||
var c = 1;
|
var c = 1;
|
||||||
!function f() {
|
!function f() {
|
||||||
var o_p = --c && f();
|
var o, o_p = --c && f();
|
||||||
+{} || console.log("PASS");
|
+{} || console.log("PASS");
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
@@ -1042,9 +1045,7 @@ issue_3945_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
function f() {
|
function f() {
|
||||||
o.p;
|
o.p;
|
||||||
var o = {
|
var o, o_q = 0;
|
||||||
q: 0,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1063,9 +1064,7 @@ issue_3945_2: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(typeof o);
|
console.log(typeof o);
|
||||||
var o = {
|
var o, o_p = 0;
|
||||||
p: 0,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
}
|
}
|
||||||
@@ -1134,10 +1133,46 @@ issue_4985: {
|
|||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a_p = 42;
|
var a, a_p = 42;
|
||||||
console.log(function() {
|
console.log(function() {
|
||||||
({});
|
({});
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5182: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
merge_vars: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = console;
|
||||||
|
log = o.log;
|
||||||
|
o = {
|
||||||
|
p: function(a) {
|
||||||
|
console.log(a ? "PASS" : "FAIL");
|
||||||
|
return a;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
log(o.p(42));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o_p = console;
|
||||||
|
log = o_p.log;
|
||||||
|
o_p = function(a) {
|
||||||
|
console.log(a ? "PASS" : "FAIL");
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
log(o_p(42));
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"42",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ issue_2295: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_4487: {
|
issue_4487_1: {
|
||||||
options = {
|
options = {
|
||||||
functions: true,
|
functions: true,
|
||||||
hoist_vars: true,
|
hoist_vars: true,
|
||||||
@@ -150,16 +150,64 @@ issue_4487: {
|
|||||||
};
|
};
|
||||||
var b = a();
|
var b = a();
|
||||||
}
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function f() {
|
||||||
|
var f = console.log(typeof f);
|
||||||
|
};
|
||||||
|
a();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4487_2: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
keep_fnames: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function f() {
|
||||||
|
var f = console.log(typeof f);
|
||||||
|
};
|
||||||
|
var b = a();
|
||||||
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function a() {
|
function a() {
|
||||||
var f;
|
var f = console.log(typeof f);
|
||||||
console.log(typeof f);
|
|
||||||
}
|
}
|
||||||
a();
|
a();
|
||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4487_3: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
keep_fnames: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function f() {
|
||||||
|
var f = console.log(typeof f);
|
||||||
|
};
|
||||||
|
var b = a();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function a() {
|
||||||
|
console.log(typeof void 0);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4489: {
|
issue_4489: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -251,18 +299,18 @@ issue_4839: {
|
|||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = function(a, b) {
|
var log = console.log, o = function(a, b) {
|
||||||
return b && b;
|
return b && b;
|
||||||
}("foo");
|
}("foo");
|
||||||
for (var k in o)
|
for (var k in o)
|
||||||
throw "FAIL";
|
throw "FAIL";
|
||||||
console.log("PASS");
|
log("PASS");
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var k, o = void 0;
|
var k, log = console.log;
|
||||||
for (k in o)
|
for (k in void 0)
|
||||||
throw "FAIL";
|
throw "FAIL";
|
||||||
console.log("PASS");
|
log("PASS");
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
@@ -288,8 +336,7 @@ issue_4859: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(function f(a) {
|
(function f(a) {
|
||||||
var d = 1 / 0, d = Infinity;
|
console.log(Infinity);
|
||||||
console.log(d);
|
|
||||||
return f;
|
return f;
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
@@ -395,3 +442,61 @@ issue_4898: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5187: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var a = 42;
|
||||||
|
do {
|
||||||
|
var b = { 0: a++ };
|
||||||
|
} while (console.log(b[b ^= 0]));
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
var b, a = 42;
|
||||||
|
do {
|
||||||
|
b = { 0: a++ };
|
||||||
|
} while (console.log(b[b ^= 0]));
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5195: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var a;
|
||||||
|
do {
|
||||||
|
var b = { p: a };
|
||||||
|
} while (console.log(b += ""));
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
var a, b;
|
||||||
|
do {
|
||||||
|
b = { p: a };
|
||||||
|
} while (console.log(b += ""));
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "[object Object]"
|
||||||
|
}
|
||||||
|
|||||||
@@ -489,6 +489,116 @@ join_object_assignments_regex: {
|
|||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chained_assignments: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a, b = a = {};
|
||||||
|
b.p = "PASS";
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, b = a = {
|
||||||
|
p: "PASS",
|
||||||
|
};
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
folded_assignments_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = {};
|
||||||
|
a[a.PASS = 42] = "PASS";
|
||||||
|
console.log(a[42], a.PASS);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = {
|
||||||
|
PASS: 42,
|
||||||
|
42: "PASS",
|
||||||
|
};
|
||||||
|
console.log(a[42], a.PASS);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
}
|
||||||
|
|
||||||
|
folded_assignments_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = {};
|
||||||
|
a[42] = "FAIL";
|
||||||
|
a[a.PASS = 42] = "PASS";
|
||||||
|
console.log(a[42], a.PASS);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
var a = {
|
||||||
|
42: "FAIL",
|
||||||
|
PASS: 42,
|
||||||
|
};
|
||||||
|
a[42] = "PASS";
|
||||||
|
console.log(a[42], a.PASS);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
}
|
||||||
|
|
||||||
|
inlined_assignments: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
(a = {}).p = "PASS";
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = {
|
||||||
|
p: "PASS",
|
||||||
|
};
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
typescript_enum: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_props: true,
|
||||||
|
inline: true,
|
||||||
|
join_vars: true,
|
||||||
|
passes: 4,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var Enum;
|
||||||
|
(function (Enum) {
|
||||||
|
Enum[Enum.PASS = 42] = "PASS";
|
||||||
|
})(Enum || (Enum = {}));
|
||||||
|
console.log(Enum[42], Enum.PASS);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS", 42);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
}
|
||||||
|
|
||||||
issue_2816: {
|
issue_2816: {
|
||||||
options = {
|
options = {
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
@@ -1183,3 +1293,26 @@ assign_sequence_var: {
|
|||||||
"1 2 3",
|
"1 2 3",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5175: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function log(f) {
|
||||||
|
console.log(f(), A.p);
|
||||||
|
}
|
||||||
|
log(function() {
|
||||||
|
return (A = {}).p = "PASS";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function log(f) {
|
||||||
|
console.log(f(), A.p);
|
||||||
|
}
|
||||||
|
log(function() {
|
||||||
|
return (A = {}).p = "PASS";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -83,8 +83,9 @@ labels_5: {
|
|||||||
conditionals: true,
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
|
unused: true,
|
||||||
}
|
}
|
||||||
// should keep the break-s in the following
|
// should keep `break`s below
|
||||||
input: {
|
input: {
|
||||||
while (foo) {
|
while (foo) {
|
||||||
if (bar) break;
|
if (bar) break;
|
||||||
@@ -100,8 +101,8 @@ labels_5: {
|
|||||||
if (bar) break;
|
if (bar) break;
|
||||||
console.log("foo");
|
console.log("foo");
|
||||||
}
|
}
|
||||||
out: while (foo) {
|
while (foo) {
|
||||||
if (bar) break out;
|
if (bar) break;
|
||||||
console.log("foo");
|
console.log("foo");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,23 +190,22 @@ labels_10: {
|
|||||||
conditionals: true,
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
out: while (foo) {
|
out: while (42) {
|
||||||
x();
|
console.log("PASS");
|
||||||
y();
|
|
||||||
break out;
|
break out;
|
||||||
z();
|
console.log("FAIL");
|
||||||
k();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
expect: {
|
expect: {
|
||||||
out: while (foo) {
|
while (42) {
|
||||||
x();
|
console.log("PASS");
|
||||||
y();
|
break;
|
||||||
break out;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_4466_1: {
|
issue_4466_1: {
|
||||||
|
|||||||
@@ -476,9 +476,9 @@ issue_4112: {
|
|||||||
try {
|
try {
|
||||||
throw 42;
|
throw 42;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
var a = e;
|
var o = e;
|
||||||
for (e in a);
|
for (e in o);
|
||||||
a = function() {};
|
function a() {}
|
||||||
console.log(typeof a);
|
console.log(typeof a);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
@@ -3377,3 +3377,60 @@ issue_4956_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5182: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_props: true,
|
||||||
|
inline: true,
|
||||||
|
merge_vars: true,
|
||||||
|
passes: 4,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
var con = console;
|
||||||
|
} catch (x) {}
|
||||||
|
global.log = con.log;
|
||||||
|
var jump = function(x) {
|
||||||
|
console.log("JUMP:", x * 10);
|
||||||
|
return x + x;
|
||||||
|
};
|
||||||
|
var jump2 = jump;
|
||||||
|
var run = function(x) {
|
||||||
|
console.log("RUN:", x * -10);
|
||||||
|
return x * x;
|
||||||
|
};
|
||||||
|
var run2 = run;
|
||||||
|
var bar = (x, y) => {
|
||||||
|
console.log("BAR:", x + y);
|
||||||
|
return x - y;
|
||||||
|
};
|
||||||
|
var bar2 = bar;
|
||||||
|
var obj = {
|
||||||
|
foo: bar2,
|
||||||
|
go: run2,
|
||||||
|
not_used: jump2,
|
||||||
|
};
|
||||||
|
console.log(obj.foo(1, 2), global.log("PASS"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
var con = console;
|
||||||
|
} catch (x) {}
|
||||||
|
global.log = con.log,
|
||||||
|
console.log((console.log("BAR:", 3), -1), global.log("PASS"));
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"BAR: 3",
|
||||||
|
"PASS",
|
||||||
|
"-1 undefined",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ assign_parentheses_dot: {
|
|||||||
input: {
|
input: {
|
||||||
(console?.log).name.p = console.log("PASS");
|
(console?.log).name.p = console.log("PASS");
|
||||||
}
|
}
|
||||||
expect_exact: '(console?.log.name).p=console.log("PASS");'
|
expect_exact: '(console?.log).name.p=console.log("PASS");'
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=14"
|
node_version: ">=14"
|
||||||
}
|
}
|
||||||
@@ -72,6 +72,26 @@ assign_no_parentheses: {
|
|||||||
node_version: ">=14"
|
node_version: ">=14"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
call_parentheses: {
|
||||||
|
input: {
|
||||||
|
(function(o) {
|
||||||
|
console.log(o.f("FAIL"), (o.f)("FAIL"), (0, o.f)(42));
|
||||||
|
console.log(o?.f("FAIL"), (o?.f)("FAIL"), (0, o?.f)(42));
|
||||||
|
})({
|
||||||
|
a: "PASS",
|
||||||
|
f(b) {
|
||||||
|
return this.a || b;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_exact: '(function(o){console.log(o.f("FAIL"),o.f("FAIL"),(0,o.f)(42));console.log(o?.f("FAIL"),(o?.f)("FAIL"),(0,o?.f)(42))})({a:"PASS",f(b){return this.a||b}});'
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS PASS 42",
|
||||||
|
"PASS PASS 42",
|
||||||
|
]
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
unary_parentheses: {
|
unary_parentheses: {
|
||||||
input: {
|
input: {
|
||||||
var o = { p: 41 };
|
var o = { p: 41 };
|
||||||
@@ -237,6 +257,99 @@ trim_2: {
|
|||||||
node_version: ">=14"
|
node_version: ">=14"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trim_dot_call_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
optional_chains: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(null?.f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
trim_dot_call_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
optional_chains: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
(null?.p)();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
(void 0)();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
trim_dot_call_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
optional_chains: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
({ p: null })?.p();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
null();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
trim_dot_sub: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
optional_chains: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(null?.p[42]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
trim_sub_call_call: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
optional_chains: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(null?.[42]()());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4906: {
|
issue_4906: {
|
||||||
options = {
|
options = {
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
|
|||||||
@@ -1510,3 +1510,71 @@ issue_5093_quote_style: {
|
|||||||
expect_exact: 'console.log({a:true,\'42\':"PASS","null":[]}[6*7]);'
|
expect_exact: 'console.log({a:true,\'42\':"PASS","null":[]}[6*7]);'
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object_methods: {
|
||||||
|
options = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
p() {
|
||||||
|
console.log("FAIL 1");
|
||||||
|
},
|
||||||
|
*q() {
|
||||||
|
console.log("FAIL 2");
|
||||||
|
},
|
||||||
|
async r() {
|
||||||
|
console.log("FAIL 3");
|
||||||
|
},
|
||||||
|
async *s() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
}).s().next();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
[
|
||||||
|
() => {
|
||||||
|
console.log("FAIL 1");
|
||||||
|
},
|
||||||
|
function*() {
|
||||||
|
console.log("FAIL 2");
|
||||||
|
},
|
||||||
|
async () => {
|
||||||
|
console.log("FAIL 3");
|
||||||
|
},
|
||||||
|
async function*() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
][3]().next();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=10"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5177: {
|
||||||
|
options = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
var o = { a: "PASS" };
|
||||||
|
o.p = {
|
||||||
|
q() {
|
||||||
|
return this.a;
|
||||||
|
},
|
||||||
|
}.q;
|
||||||
|
console.log(o.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL";
|
||||||
|
var o = { a: "PASS" };
|
||||||
|
o.p = {
|
||||||
|
q() {
|
||||||
|
return this.a;
|
||||||
|
},
|
||||||
|
}.q;
|
||||||
|
console.log(o.p());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1640,6 +1640,26 @@ nested_property_assignments_3: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nested_property_assignments_4: {
|
||||||
|
options = {
|
||||||
|
pure_getters: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var n, o = { p: { q: { r: "PASS" } } };
|
||||||
|
(n = o.p).r = n.q.r;
|
||||||
|
console.log(o.p.r);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var n, o = { p: { q: { r: "PASS" } } };
|
||||||
|
(n = o.p).r = n.q.r;
|
||||||
|
console.log(o.p.r);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4939: {
|
issue_4939: {
|
||||||
options = {
|
options = {
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
|
|||||||
@@ -7320,6 +7320,64 @@ local_assignment_loop: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local_assignment_modified: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
(a = a || {}).p = 42;
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
(a = {}).p = 42;
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
local_declaration: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
a || console.log(a = "PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
local_definition_modified: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = a || {};
|
||||||
|
a.p = 42;
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = {};
|
||||||
|
a.p = 42;
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
issue_3957_1: {
|
issue_3957_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -7435,6 +7493,7 @@ issue_4030: {
|
|||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -636,6 +636,24 @@ keep_rest_lambda_2: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drop_new_function: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new function(...{
|
||||||
|
[console.log("PASS")]: a,
|
||||||
|
}) {}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
void ([ ... {
|
||||||
|
[console.log("PASS")]: [].e,
|
||||||
|
}] = []);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4525_1: {
|
issue_4525_1: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
@@ -1026,13 +1044,13 @@ issue_5100_1: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a;
|
var a;
|
||||||
[ {
|
({
|
||||||
p: {},
|
p: {},
|
||||||
...a
|
...a
|
||||||
} ] = [ {
|
} = [ {
|
||||||
p: [ a = 42["q"] ],
|
p: [ a = 42["q"] ],
|
||||||
r: "PASS",
|
r: "PASS",
|
||||||
} ];
|
} ][0]);
|
||||||
console.log(a.r);
|
console.log(a.r);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -1059,13 +1077,131 @@ issue_5100_2: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a;
|
var a;
|
||||||
[ {
|
({
|
||||||
p: {},
|
p: {},
|
||||||
...a
|
...a
|
||||||
} ] = [ {
|
} = [ {
|
||||||
p: [ console.log("PASS"), a = 42["q"] ],
|
p: [ console.log("PASS"), a = 42["q"] ],
|
||||||
} ];
|
} ][0]);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=10"
|
node_version: ">=10"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5108: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
rests: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function([ ...[ a ] ]) {
|
||||||
|
return a;
|
||||||
|
}([ "PASS", "FAIL" ]));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function([]) {
|
||||||
|
return "PASS";
|
||||||
|
}([ "PASS", "FAIL" ]));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5128_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
return function f(...[ a ]) {
|
||||||
|
return a;
|
||||||
|
}("PASS");
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function f(...[ a ]) {
|
||||||
|
return a;
|
||||||
|
}("PASS"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5128_2: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
keep_fnames: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
return function f(...[ a ]) {
|
||||||
|
return a;
|
||||||
|
}("PASS");
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function f(...[ a ]) {
|
||||||
|
return a;
|
||||||
|
}("PASS"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5165_1: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
rests: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function([ ...a ]) {
|
||||||
|
switch (a) {
|
||||||
|
case a:
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
}([]));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function([ ...a ]) {
|
||||||
|
return "PASS";
|
||||||
|
}([]));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5165_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
rests: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(...a) {
|
||||||
|
switch (a) {
|
||||||
|
case a:
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|||||||
@@ -201,3 +201,20 @@ issue_4811_2: {
|
|||||||
expect_stdout: "PASS [object global] true"
|
expect_stdout: "PASS [object global] true"
|
||||||
node_version: ">=8"
|
node_version: ">=8"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5197: {
|
||||||
|
rename = true
|
||||||
|
input: {
|
||||||
|
function f(async) {
|
||||||
|
async(")=>{}");
|
||||||
|
}
|
||||||
|
console.log("" + this.__proto__);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
a(")=>{}");
|
||||||
|
}
|
||||||
|
console.log("" + this.__proto__);
|
||||||
|
}
|
||||||
|
expect_stdout: "[object global]"
|
||||||
|
}
|
||||||
|
|||||||
@@ -131,6 +131,105 @@ malformed_escape: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
booleans: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
evaluate: true,
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
console.log(`$${a}${a}` ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
console.log("$" + a + a ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
escape_placeholder_1: {
|
||||||
|
options = {
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`\${\n`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(`\${
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"${",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
escape_placeholder_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`\n${"${"}\n`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(`
|
||||||
|
\${
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"",
|
||||||
|
"${",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
escape_placeholder_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`\n$${"{"}\n`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(`
|
||||||
|
\${
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"",
|
||||||
|
"${",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
escape_placeholder_4: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`\n${"$"}${"{"}\n`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(`
|
||||||
|
\${
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"",
|
||||||
|
"${",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
evaluate: {
|
evaluate: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -174,7 +273,7 @@ partial_evaluate: {
|
|||||||
console.log(`${6 * 7} foo ${console ? `PA` + "SS" : `FA` + `IL`}`);
|
console.log(`${6 * 7} foo ${console ? `PA` + "SS" : `FA` + `IL`}`);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(`42 foo ${console ? "PASS" : "FAIL"}`);
|
console.log("42 foo " + (console ? "PASS" : "FAIL"));
|
||||||
}
|
}
|
||||||
expect_stdout: "42 foo PASS"
|
expect_stdout: "42 foo PASS"
|
||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
@@ -204,7 +303,7 @@ malformed_evaluate_2: {
|
|||||||
console.log(`\u0${0}b${5}`);
|
console.log(`\u0${0}b${5}`);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(`\u0${0}b5`);
|
console.log(`\u00b` + 5);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
@@ -357,13 +456,14 @@ issue_4604: {
|
|||||||
issue_4606: {
|
issue_4606: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
strings: true,
|
||||||
templates: true,
|
templates: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(`${typeof A} ${"\r"} ${"\\"} ${"`"}`);
|
console.log(`${typeof A} ${"\r"} ${"\\"} ${"`"}`);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(`${typeof A} \r \\ \``);
|
console.log(typeof A + " \r \\ `");
|
||||||
}
|
}
|
||||||
expect_stdout: "undefined \r \\ `"
|
expect_stdout: "undefined \r \\ `"
|
||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
@@ -434,3 +534,238 @@ issue_4931: {
|
|||||||
]
|
]
|
||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5125_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
strings: true,
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`PASS ${typeof A}`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS " + typeof A);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS undefined"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5125_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
strings: true,
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`PASS
|
||||||
|
${typeof A}`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(`PASS
|
||||||
|
` + typeof A);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5125_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
strings: true,
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`PASS\n${typeof A}`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(`PASS
|
||||||
|
` + typeof A);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5125_4: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
strings: true,
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`PASS
|
||||||
|
|
||||||
|
${typeof A}`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(`PASS
|
||||||
|
|
||||||
|
` + typeof A);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5125_5: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
strings: true,
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`PASS\n\n${typeof A}`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(`PASS
|
||||||
|
|
||||||
|
` + typeof A);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5125_6: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
strings: true,
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`${typeof A} ${typeof B} PASS`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof A + ` ${typeof B} PASS`);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined undefined PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5125_7: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
strings: true,
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`${typeof A} ${typeof B} ${typeof C} PASS`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof A + ` ${typeof B} ${typeof C} PASS`);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined undefined undefined PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5125_8: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
strings: true,
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`${typeof A}${typeof B}${typeof C} PASS`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof A + typeof B + typeof C + " PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "undefinedundefinedundefined PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5136: {
|
||||||
|
options = {
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`${A = []}${A[0] = 42}`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(`` + (A = []) + (A[0] = 42));
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5145_1: {
|
||||||
|
options = {
|
||||||
|
strings: true,
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [];
|
||||||
|
console.log(`${a}${a[0] = 42}
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = [];
|
||||||
|
console.log(`${a}${a[0] = 42}
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"42",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5145_2: {
|
||||||
|
options = {
|
||||||
|
strings: true,
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [];
|
||||||
|
console.log(`${a}${a}${a[0] = 42}
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = [];
|
||||||
|
console.log("" + a + a + (a[0] = 42) + `
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"42",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5199: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function() {
|
||||||
|
console.log(typeof b);
|
||||||
|
}``;
|
||||||
|
{
|
||||||
|
const b = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function() {
|
||||||
|
console.log(typeof b);
|
||||||
|
}``;
|
||||||
|
{
|
||||||
|
const b = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ hoist_props_const: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var o_p = "PASS";
|
var o = 0, o_p = "PASS";
|
||||||
console.log(o_p);
|
console.log(o_p);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -136,7 +136,7 @@ hoist_props_let: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
"use strict";
|
"use strict";
|
||||||
var o_p = "PASS";
|
var o, o_p = "PASS";
|
||||||
console.log(o_p);
|
console.log(o_p);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ pause_resume: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
arrow_yield: {
|
arrow_yield_1: {
|
||||||
input: {
|
input: {
|
||||||
yield = "PASS";
|
yield = "PASS";
|
||||||
console.log(function*() {
|
console.log(function*() {
|
||||||
@@ -108,6 +108,18 @@ arrow_yield: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arrow_yield_2: {
|
||||||
|
input: {
|
||||||
|
console.log(typeof function *() {
|
||||||
|
// Syntax error on Node.js v6+
|
||||||
|
return (yield) => {};
|
||||||
|
}().next().value);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(typeof function*(){return(yield)=>{}}().next().value);"
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: "4"
|
||||||
|
}
|
||||||
|
|
||||||
for_of: {
|
for_of: {
|
||||||
input: {
|
input: {
|
||||||
function* f() {
|
function* f() {
|
||||||
@@ -1275,3 +1287,25 @@ issue_5076: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5177: {
|
||||||
|
options = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof function*() {
|
||||||
|
return {
|
||||||
|
p(yield) {},
|
||||||
|
}.p;
|
||||||
|
}().next().value);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof function*() {
|
||||||
|
return {
|
||||||
|
p(yield) {},
|
||||||
|
}.p;
|
||||||
|
}().next().value);
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
1
test/input/invalid/optional-template.js
Normal file
1
test/input/invalid/optional-template.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
console?.log``;
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
// (beautified)
|
// (beautified)
|
||||||
console.log(function() {
|
console.log(1 + .1 + .1);
|
||||||
return 1 + .1 + .1;
|
|
||||||
}());
|
|
||||||
// output: 1.2000000000000002
|
// output: 1.2000000000000002
|
||||||
//
|
//
|
||||||
// minify: 1.2
|
// minify: 1.2
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ if (typeof phantom == "undefined") {
|
|||||||
(function install() {
|
(function install() {
|
||||||
npm([
|
npm([
|
||||||
"install",
|
"install",
|
||||||
|
"graceful-fs@4.2.6",
|
||||||
|
"is-my-json-valid@2.20.5",
|
||||||
"phantomjs-prebuilt@2.1.14",
|
"phantomjs-prebuilt@2.1.14",
|
||||||
"--no-audit",
|
"--no-audit",
|
||||||
"--no-optional",
|
"--no-optional",
|
||||||
|
|||||||
@@ -721,6 +721,20 @@ describe("bin/uglifyjs", function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("Should throw syntax error (console?.log``)", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/invalid/optional-template.js";
|
||||||
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/optional-template.js:1,12",
|
||||||
|
"console?.log``;",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Invalid template on optional chain",
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
it("Should handle literal string as source map input", function(done) {
|
it("Should handle literal string as source map input", function(done) {
|
||||||
var command = [
|
var command = [
|
||||||
uglifyjscmd,
|
uglifyjscmd,
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ describe("comments", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should correctly preserve new lines around comments", function() {
|
it("Should correctly preserve new lines around comments", function() {
|
||||||
var tests = [
|
[
|
||||||
[
|
[
|
||||||
"// foo",
|
"// foo",
|
||||||
"// bar",
|
"// bar",
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var exec = require("child_process").exec;
|
var exec = require("child_process").exec;
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
var readFileSync = require("fs").readFileSync;
|
|
||||||
|
|
||||||
describe("bin/uglifyjs with input file globs", function() {
|
describe("bin/uglifyjs with input file globs", function() {
|
||||||
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var UglifyJS = require("../..");
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
describe("let", function() {
|
describe("let", function() {
|
||||||
this.timeout(30000);
|
this.timeout(30000);
|
||||||
@@ -54,4 +54,43 @@ describe("let", function() {
|
|||||||
assert.notStrictEqual(result.indexOf('v["' + name + '"]'), -1);
|
assert.notStrictEqual(result.indexOf('v["' + name + '"]'), -1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("Should parse `let` as name correctly", function() {
|
||||||
|
[
|
||||||
|
"for(var let;let;let)let;",
|
||||||
|
"function let(let){let}",
|
||||||
|
].forEach(function(code) {
|
||||||
|
var ast = UglifyJS.parse(code);
|
||||||
|
assert.strictEqual(ast.print_to_string(), code);
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse('"use strict";' + code);
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error && e.message == "Unexpected let in strict mode";
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw on ambiguous use of `let`", function() {
|
||||||
|
[
|
||||||
|
"export let",
|
||||||
|
[
|
||||||
|
"let",
|
||||||
|
"console.log(42)",
|
||||||
|
].join("\n"),
|
||||||
|
[
|
||||||
|
"let",
|
||||||
|
"[ console.log(42) ]",
|
||||||
|
].join("\n"),
|
||||||
|
[
|
||||||
|
"let",
|
||||||
|
"{",
|
||||||
|
" console.log(42)",
|
||||||
|
"}",
|
||||||
|
].join("\n"),
|
||||||
|
].forEach(function(code) {
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse(code);
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ describe("minify", function() {
|
|||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code, "print(42);");
|
assert.strictEqual(result.code, "print(42);");
|
||||||
assert.strictEqual(JSON.stringify(options), value);
|
assert.strictEqual(JSON.stringify(options), value);
|
||||||
})
|
});
|
||||||
it("Should skip inherited keys from `files`", function() {
|
it("Should skip inherited keys from `files`", function() {
|
||||||
var files = Object.create({ skip: this });
|
var files = Object.create({ skip: this });
|
||||||
files[0] = "alert(1 + 1)";
|
files[0] = "alert(1 + 1)";
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var exec = require("child_process").exec;
|
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var reduce_test = require("../reduce");
|
var reduce_test = require("../reduce");
|
||||||
var semver = require("semver");
|
var semver = require("semver");
|
||||||
@@ -282,35 +281,40 @@ describe("test/reduce.js", function() {
|
|||||||
});
|
});
|
||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.deepEqual(result.warnings, []);
|
assert.deepEqual(result.warnings, []);
|
||||||
assert.strictEqual(result.code.replace(/function \(/g, "function("), (semver.satisfies(process.version, "<=0.10") ? [
|
if (semver.satisfies(process.version, "<=0.10")) {
|
||||||
"// Can't reproduce test failure",
|
assert.strictEqual(result.code, [
|
||||||
"// minify options: {",
|
"// Can't reproduce test failure",
|
||||||
'// "compress": false,',
|
"// minify options: {",
|
||||||
'// "mangle": false,',
|
'// "compress": false,',
|
||||||
'// "output": {',
|
'// "mangle": false,',
|
||||||
'// "beautify": true',
|
'// "output": {',
|
||||||
"// }",
|
'// "beautify": true',
|
||||||
"// }",
|
"// }",
|
||||||
] : [
|
"// }",
|
||||||
[
|
].join("\n"));
|
||||||
"try{",
|
} else {
|
||||||
"null[function(){}]",
|
var message = result.code.split(/\n/, 3)[1].slice("// output: ".length);
|
||||||
"}catch(e){",
|
assert.strictEqual(result.code, [
|
||||||
"console.log(e)",
|
[
|
||||||
"}",
|
"try{",
|
||||||
].join(""),
|
"null[function(){}]",
|
||||||
"// output: TypeError: Cannot read property 'function(){}' of null",
|
"}catch(e){",
|
||||||
"// ",
|
"console.log(e)",
|
||||||
"// minify: TypeError: Cannot read property 'function() {}' of null",
|
"}",
|
||||||
"// ",
|
].join(""),
|
||||||
"// options: {",
|
"// output: " + message,
|
||||||
'// "compress": false,',
|
"// ",
|
||||||
'// "mangle": false,',
|
"// minify: " + message.replace("(){}", "() {}"),
|
||||||
'// "output": {',
|
"// ",
|
||||||
'// "beautify": true',
|
"// options: {",
|
||||||
"// }",
|
'// "compress": false,',
|
||||||
"// }",
|
'// "mangle": false,',
|
||||||
]).join("\n"));
|
'// "output": {',
|
||||||
|
'// "beautify": true',
|
||||||
|
"// }",
|
||||||
|
"// }",
|
||||||
|
].join("\n"));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
it("Should maintain block-scope for const/let", function() {
|
it("Should maintain block-scope for const/let", function() {
|
||||||
if (semver.satisfies(process.version, "<4")) return;
|
if (semver.satisfies(process.version, "<4")) return;
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ describe("sourcemaps", function() {
|
|||||||
it("Should not modify input source map", function() {
|
it("Should not modify input source map", function() {
|
||||||
var orig = get_map();
|
var orig = get_map();
|
||||||
var original = JSON.stringify(orig);
|
var original = JSON.stringify(orig);
|
||||||
var map = prepare_map(orig);
|
prepare_map(orig);
|
||||||
assert.strictEqual(JSON.stringify(orig), original);
|
assert.strictEqual(JSON.stringify(orig), original);
|
||||||
});
|
});
|
||||||
it("Should copy over original sourcesContent", function() {
|
it("Should copy over original sourcesContent", function() {
|
||||||
|
|||||||
@@ -4,34 +4,27 @@ var UglifyJS = require("../..");
|
|||||||
|
|
||||||
describe("spidermonkey export/import sanity test", function() {
|
describe("spidermonkey export/import sanity test", function() {
|
||||||
it("Should produce a functional build when using --self with spidermonkey", function(done) {
|
it("Should produce a functional build when using --self with spidermonkey", function(done) {
|
||||||
this.timeout(60000);
|
this.timeout(120000);
|
||||||
|
|
||||||
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
|
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||||
var command = uglifyjs + " --self -cm --wrap SpiderUglify -o spidermonkey | " +
|
var command = [
|
||||||
uglifyjs + " -p spidermonkey -cm";
|
uglifyjs + " --self -cm --wrap SpiderUglify -o spidermonkey",
|
||||||
|
uglifyjs + " -p spidermonkey -cm",
|
||||||
exec(command, {
|
].join(" | ");
|
||||||
maxBuffer: 1048576
|
exec(command, { maxBuffer: 1048576 }, function(err, stdout) {
|
||||||
}, function(err, stdout) {
|
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
eval(stdout);
|
eval(stdout);
|
||||||
assert.strictEqual(typeof SpiderUglify, "object");
|
assert.strictEqual(typeof SpiderUglify, "object");
|
||||||
var result = SpiderUglify.minify("foo([true,,2+3]);");
|
var result = SpiderUglify.minify("foo([true,,2+3]);");
|
||||||
assert.strictEqual(result.error, undefined);
|
assert.strictEqual(result.error, undefined);
|
||||||
assert.strictEqual(result.code, "foo([!0,,5]);");
|
assert.strictEqual(result.code, "foo([!0,,5]);");
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should not add unnecessary escape slashes to regexps", function() {
|
it("Should not add unnecessary escape slashes to RegExp", function() {
|
||||||
var input = "/[\\\\/]/;";
|
var input = "/[\\\\/]/;";
|
||||||
var ast = UglifyJS.parse(input).to_mozilla_ast();
|
var ast = UglifyJS.parse(input).to_mozilla_ast();
|
||||||
assert.equal(
|
assert.strictEqual(UglifyJS.AST_Node.from_mozilla_ast(ast).print_to_string(), input);
|
||||||
UglifyJS.AST_Node.from_mozilla_ast(ast).print_to_string(),
|
|
||||||
input
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should judge between directives and strings correctly on import", function() {
|
it("Should judge between directives and strings correctly on import", function() {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ describe("String literals", function() {
|
|||||||
'"\u2029"',
|
'"\u2029"',
|
||||||
].forEach(function(input) {
|
].forEach(function(input) {
|
||||||
assert.throws(function() {
|
assert.throws(function() {
|
||||||
var ast = UglifyJS.parse(input);
|
UglifyJS.parse(input);
|
||||||
}, function(e) {
|
}, function(e) {
|
||||||
return e instanceof UglifyJS.JS_Parse_Error
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
&& e.message === "Unterminated string constant";
|
&& e.message === "Unterminated string constant";
|
||||||
@@ -44,7 +44,7 @@ describe("String literals", function() {
|
|||||||
'"use strict";\n"\\011"',
|
'"use strict";\n"\\011"',
|
||||||
].forEach(function(input) {
|
].forEach(function(input) {
|
||||||
assert.throws(function() {
|
assert.throws(function() {
|
||||||
var output = UglifyJS.parse(input);
|
UglifyJS.parse(input);
|
||||||
}, function(e) {
|
}, function(e) {
|
||||||
return e instanceof UglifyJS.JS_Parse_Error
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
&& e.message === "Legacy octal escape sequences are not allowed in strict mode";
|
&& e.message === "Legacy octal escape sequences are not allowed in strict mode";
|
||||||
|
|||||||
@@ -34,20 +34,20 @@ describe("Template literals", function() {
|
|||||||
[
|
[
|
||||||
// native line breaks
|
// native line breaks
|
||||||
[ "`foo\nbar`", "`foo\nbar`" ],
|
[ "`foo\nbar`", "`foo\nbar`" ],
|
||||||
[ "`foo\rbar`", "`foo\rbar`" ],
|
[ "`foo\rbar`", "`foo\nbar`" ],
|
||||||
[ "`foo\r\nbar`", "`foo\nbar`" ],
|
[ "`foo\r\nbar`", "`foo\nbar`" ],
|
||||||
[ "`foo\r\n\rbar`", "`foo\n\rbar`" ],
|
[ "`foo\r\n\rbar`", "`foo\n\nbar`" ],
|
||||||
// escaped line breaks
|
// escaped line breaks
|
||||||
[ "`foo\\nbar`", "`foo\\nbar`" ],
|
[ "`foo\\nbar`", "`foo\\nbar`" ],
|
||||||
[ "`foo\\rbar`", "`foo\\rbar`" ],
|
[ "`foo\\rbar`", "`foo\\rbar`" ],
|
||||||
[ "`foo\r\\nbar`", "`foo\r\\nbar`" ],
|
[ "`foo\r\\nbar`", "`foo\n\\nbar`" ],
|
||||||
[ "`foo\\r\nbar`", "`foo\\r\nbar`" ],
|
[ "`foo\\r\nbar`", "`foo\\r\nbar`" ],
|
||||||
[ "`foo\\r\\nbar`", "`foo\\r\\nbar`" ],
|
[ "`foo\\r\\nbar`", "`foo\\r\\nbar`" ],
|
||||||
// continuation
|
// continuation
|
||||||
[ "`foo\\\nbar`", "`foo\\\nbar`" ],
|
[ "`foo\\\nbar`", "`foo\\\nbar`" ],
|
||||||
[ "`foo\\\rbar`", "`foo\\\rbar`" ],
|
[ "`foo\\\rbar`", "`foo\\\nbar`" ],
|
||||||
[ "`foo\\\r\nbar`", "`foo\\\nbar`" ],
|
[ "`foo\\\r\nbar`", "`foo\\\nbar`" ],
|
||||||
[ "`foo\\\r\n\rbar`", "`foo\\\n\rbar`" ],
|
[ "`foo\\\r\n\rbar`", "`foo\\\n\nbar`" ],
|
||||||
[ "`foo\\\\nbar`", "`foo\\\\nbar`" ],
|
[ "`foo\\\\nbar`", "`foo\\\\nbar`" ],
|
||||||
[ "`foo\\\\rbar`", "`foo\\\\rbar`" ],
|
[ "`foo\\\\rbar`", "`foo\\\\rbar`" ],
|
||||||
[ "`foo\\\\r\nbar`", "`foo\\\\r\nbar`" ],
|
[ "`foo\\\\r\nbar`", "`foo\\\\r\nbar`" ],
|
||||||
|
|||||||
@@ -215,9 +215,9 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
// hoist and return expressions from the IIFE function expression
|
// hoist and return expressions from the IIFE function expression
|
||||||
var seq = [];
|
var seq = [];
|
||||||
node.expression.body.forEach(function(node) {
|
node.expression.body.forEach(function(node) {
|
||||||
var expr = expr instanceof U.AST_Exit ? node.value : node.body;
|
var expr = node instanceof U.AST_Exit ? node.value : node.body;
|
||||||
if (expr instanceof U.AST_Node && !U.is_statement(expr) && can_hoist(expr)) {
|
if (expr instanceof U.AST_Node && !U.is_statement(expr) && can_hoist(expr)) {
|
||||||
// collect expressions from each statements' body
|
// collect expressions from each statement's body
|
||||||
seq.push(expr);
|
seq.push(expr);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -395,7 +395,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
var expr = [
|
var expr = [
|
||||||
node.expression, // switch expression
|
node.expression, // switch expression
|
||||||
node.body[0] && node.body[0].expression, // first case expression or undefined
|
node.body[0] && node.body[0].expression, // first case expression or undefined
|
||||||
node.body[0] && node.body[0], // first case body or undefined
|
node.body[0], // first case body or undefined
|
||||||
][ (node.start._permute * steps | 0) % 4 ];
|
][ (node.start._permute * steps | 0) % 4 ];
|
||||||
node.start._permute += step;
|
node.start._permute += step;
|
||||||
if (expr && (!(expr instanceof U.AST_Statement) || !has_loopcontrol(expr, node, parent))) {
|
if (expr && (!(expr instanceof U.AST_Statement) || !has_loopcontrol(expr, node, parent))) {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ exports.run_code = semver.satisfies(process.version, "0.8") ? function(code, top
|
|||||||
if ([
|
if ([
|
||||||
/\basync[ \t]*\([\s\S]*?\)[ \t]*=>/,
|
/\basync[ \t]*\([\s\S]*?\)[ \t]*=>/,
|
||||||
/\b(async[ \t]+function|Promise|setImmediate|setInterval|setTimeout)\b/,
|
/\b(async[ \t]+function|Promise|setImmediate|setInterval|setTimeout)\b/,
|
||||||
/\basync([ \t]+|[ \t]*#|[ \t]*\*[ \t]*)[^\s()[\]{},.&|!~=*%/+-]+(\s*\(|[ \t]*=>)/,
|
/\basync([ \t]+|[ \t]*#|[ \t]*\*[ \t]*)[^\s()[\]{}#:;,.&|!~=*%/+-]+(\s*\(|[ \t]*=>)/,
|
||||||
].some(function(pattern) {
|
].some(function(pattern) {
|
||||||
return pattern.test(code);
|
return pattern.test(code);
|
||||||
})) {
|
})) {
|
||||||
@@ -51,13 +51,13 @@ exports.same_stdout = semver.satisfies(process.version, "0.12") ? function(expec
|
|||||||
};
|
};
|
||||||
exports.patch_module_statements = function(code) {
|
exports.patch_module_statements = function(code) {
|
||||||
var count = 0, imports = [];
|
var count = 0, imports = [];
|
||||||
code = code.replace(/\bexport(?:\s*\{[^}]*}\s*?(?:$|\n|;)|\s+default\b(?:\s*(\(|\{|class\s*\{|class\s+(?=extends\b)|(?:async\s+)?function\s*(?:\*\s*)?\())?|\b)/g, function(match, header) {
|
code = code.replace(/\bexport(?:\s*\{[^{}]*}\s*?(?:$|\n|;)|\s+default\b(?:\s*(\(|\{|class\s*\{|class\s+(?=extends\b)|(?:async\s+)?function\s*(?:\*\s*)?\())?|\b)/g, function(match, header) {
|
||||||
if (!header) return "";
|
if (!header) return "";
|
||||||
if (header.length == 1) return "0, " + header;
|
if (header.length == 1) return "0, " + header;
|
||||||
return header.slice(0, -1) + " _" + ++count + header.slice(-1);
|
return header.slice(0, -1) + " _" + ++count + header.slice(-1);
|
||||||
}).replace(/\bimport\.meta\b/g, function() {
|
}).replace(/\bimport\.meta\b/g, function() {
|
||||||
return '({ url: "https://example.com/path/index.html" })';
|
return '({ url: "https://example.com/path/index.html" })';
|
||||||
}).replace(/\bimport\b(?:\s*([^('"]+)\bfrom\b)?\s*(['"]).*?\2(?:$|\n|;)/g, function(match, symbols) {
|
}).replace(/\bimport\b(?:\s*([^\s('"][^('"]*)\bfrom\b)?\s*(['"]).*?\2(?:$|\n|;)/g, function(match, symbols) {
|
||||||
if (symbols) {
|
if (symbols) {
|
||||||
if (!/^[{*]/.test(symbols)) symbols = "default:" + symbols;
|
if (!/^[{*]/.test(symbols)) symbols = "default:" + symbols;
|
||||||
symbols = symbols.replace(/[{}]/g, "").trim().replace(/\s*,\s*/g, ",");
|
symbols = symbols.replace(/[{}]/g, "").trim().replace(/\s*,\s*/g, ",");
|
||||||
@@ -202,13 +202,11 @@ function setup(global, builtins, setup_log, setup_tty) {
|
|||||||
});
|
});
|
||||||
Object.defineProperties(global, props);
|
Object.defineProperties(global, props);
|
||||||
// for Node.js v8+
|
// for Node.js v8+
|
||||||
if (global.toString !== Object.prototype.toString) {
|
global.__proto__ = Object.defineProperty(Object.create(global.__proto__), "toString", {
|
||||||
global.__proto__ = Object.defineProperty(Object.create(global.__proto__), "toString", {
|
value: function() {
|
||||||
value: function() {
|
return "[object global]";
|
||||||
return "[object global]";
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function self() {
|
function self() {
|
||||||
return this;
|
return this;
|
||||||
@@ -278,11 +276,11 @@ function run_code_exec(code, toplevel, timeout) {
|
|||||||
timeout: timeout || 5000,
|
timeout: timeout || 5000,
|
||||||
});
|
});
|
||||||
if (result.status === 0) return result.stdout;
|
if (result.status === 0) return result.stdout;
|
||||||
|
var msg = ("" + result.stderr).replace(/\r\n/g, "\n");
|
||||||
if (result.error && result.error.code == "ETIMEDOUT" || /FATAL ERROR:/.test(msg)) {
|
if (result.error && result.error.code == "ETIMEDOUT" || /FATAL ERROR:/.test(msg)) {
|
||||||
return new Error("Script execution timed out.");
|
return new Error("Script execution timed out.");
|
||||||
}
|
}
|
||||||
if (result.error) return result.error;
|
if (result.error) return result.error;
|
||||||
var msg = result.stderr.replace(/\r\n/g, "\n");
|
|
||||||
var end = msg.indexOf("\n\n-----===== UNCAUGHT EXCEPTION =====-----\n\n");
|
var end = msg.indexOf("\n\n-----===== UNCAUGHT EXCEPTION =====-----\n\n");
|
||||||
var details;
|
var details;
|
||||||
if (end >= 0) {
|
if (end >= 0) {
|
||||||
|
|||||||
@@ -334,6 +334,7 @@ var VAR_NAMES = [
|
|||||||
"arguments",
|
"arguments",
|
||||||
"async",
|
"async",
|
||||||
"await",
|
"await",
|
||||||
|
"let",
|
||||||
"yield",
|
"yield",
|
||||||
];
|
];
|
||||||
var INITIAL_NAMES_LEN = VAR_NAMES.length;
|
var INITIAL_NAMES_LEN = VAR_NAMES.length;
|
||||||
@@ -352,7 +353,7 @@ var TYPEOF_OUTCOMES = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
var avoid_vars = [];
|
var avoid_vars = [];
|
||||||
var block_vars = [];
|
var block_vars = [ "let" ];
|
||||||
var lambda_vars = [];
|
var lambda_vars = [];
|
||||||
var unique_vars = [];
|
var unique_vars = [];
|
||||||
var classes = [];
|
var classes = [];
|
||||||
@@ -399,7 +400,7 @@ function mayDefer(code) {
|
|||||||
|
|
||||||
function createTopLevelCode() {
|
function createTopLevelCode() {
|
||||||
VAR_NAMES.length = INITIAL_NAMES_LEN; // prune any previous names still in the list
|
VAR_NAMES.length = INITIAL_NAMES_LEN; // prune any previous names still in the list
|
||||||
block_vars.length = 0;
|
block_vars.length = 1;
|
||||||
lambda_vars.length = 0;
|
lambda_vars.length = 0;
|
||||||
unique_vars.length = 0;
|
unique_vars.length = 0;
|
||||||
classes.length = 0;
|
classes.length = 0;
|
||||||
@@ -2027,6 +2028,7 @@ function removeAvoidVar(name) {
|
|||||||
function isBannedKeyword(name) {
|
function isBannedKeyword(name) {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case "arguments":
|
case "arguments":
|
||||||
|
case "let":
|
||||||
return in_class;
|
return in_class;
|
||||||
case "await":
|
case "await":
|
||||||
return async !== false;
|
return async !== false;
|
||||||
@@ -2078,8 +2080,8 @@ if (require.main !== module) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function run_code(code, toplevel) {
|
function run_code(code, toplevel, timeout) {
|
||||||
return sandbox.run_code(sandbox.patch_module_statements(code), toplevel);
|
return sandbox.run_code(sandbox.patch_module_statements(code), toplevel, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeln(stream, msg) {
|
function writeln(stream, msg) {
|
||||||
@@ -2350,7 +2352,7 @@ function patch_try_catch(orig, toplevel) {
|
|||||||
tries: [],
|
tries: [],
|
||||||
} ];
|
} ];
|
||||||
var tail_throw = '\nif (typeof UFUZZ_ERROR == "object") throw UFUZZ_ERROR;\n';
|
var tail_throw = '\nif (typeof UFUZZ_ERROR == "object") throw UFUZZ_ERROR;\n';
|
||||||
var re = /(?:(?:^|[\s{}):;])try|}\s*catch\s*\(([^)[{]+)\)|}\s*finally)\s*(?={)/g;
|
var re = /(?:(?:^|[\s{}):;])try|}\s*catch\s*\(([^()[{]+)\)|}\s*finally)\s*(?={)/g;
|
||||||
while (stack.length) {
|
while (stack.length) {
|
||||||
var code = stack[0].code;
|
var code = stack[0].code;
|
||||||
var offset = stack[0].offset;
|
var offset = stack[0].offset;
|
||||||
|
|||||||
Reference in New Issue
Block a user