Compare commits
29 Commits
harmony-v3
...
harmony-v3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
945db924fc | ||
|
|
087bce508a | ||
|
|
5e6f26445f | ||
|
|
fc7e33453f | ||
|
|
d052394621 | ||
|
|
4d5aeeddfb | ||
|
|
f0a99125ee | ||
|
|
1e4de2e6d3 | ||
|
|
ad139aa34d | ||
|
|
26be15f111 | ||
|
|
179f33f08a | ||
|
|
d260fe9018 | ||
|
|
96f9b8cba3 | ||
|
|
11afa816e3 | ||
|
|
8b4dcd8f3e | ||
|
|
285401ced8 | ||
|
|
9db4c42380 | ||
|
|
49f3de8397 | ||
|
|
94f93ad82d | ||
|
|
d1f085bce7 | ||
|
|
7b95b63ca1 | ||
|
|
94e5e00c03 | ||
|
|
dc6bcaa18e | ||
|
|
d58b184835 | ||
|
|
137e4c4753 | ||
|
|
b3a57ff019 | ||
|
|
3d5bc08185 | ||
|
|
0692435f01 | ||
|
|
b163b13a0b |
34
README.md
34
README.md
@@ -1,11 +1,11 @@
|
|||||||
uglify-es
|
uglify-es
|
||||||
=========
|
=========
|
||||||
|
|
||||||
**uglify-es** is an ECMAScript 2015 parser, minifier, compressor and beautifier toolkit.
|
**uglify-es** is an ECMAScript parser, minifier, compressor and beautifier toolkit for ES6+.
|
||||||
|
|
||||||
#### Note:
|
#### Note:
|
||||||
- **The `uglify-es` API and CLI is compatible with `uglify-js@3.x`.**
|
- **`uglify-es` is API/CLI compatible with `uglify-js@3`.**
|
||||||
- **`uglify-es` is not backwards compatible with the `uglify-js@2.x` API and CLI.**
|
- **`uglify-es` is not backwards compatible with `uglify-js@2`.**
|
||||||
|
|
||||||
Install
|
Install
|
||||||
-------
|
-------
|
||||||
@@ -102,6 +102,7 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
sequences.
|
sequences.
|
||||||
--config-file <file> Read `minify()` options from JSON file.
|
--config-file <file> Read `minify()` options from JSON file.
|
||||||
-d, --define <expr>[=value] Global definitions.
|
-d, --define <expr>[=value] Global definitions.
|
||||||
|
--ecma <version> Specifiy ECMAScript release: 5, 6, 7 or 8.
|
||||||
--ie8 Support non-standard Internet Explorer 8.
|
--ie8 Support non-standard Internet Explorer 8.
|
||||||
Equivalent to setting `ie8: true` in `minify()`
|
Equivalent to setting `ie8: true` in `minify()`
|
||||||
for `compress`, `mangle` and `output` options.
|
for `compress`, `mangle` and `output` options.
|
||||||
@@ -433,6 +434,9 @@ if (result.error) throw result.error;
|
|||||||
|
|
||||||
## Minify options
|
## Minify options
|
||||||
|
|
||||||
|
- `ecma` (default `undefined`) - pass `5`, `6`, `7` or `8` to override `parse`,
|
||||||
|
`compress` and `output` options.
|
||||||
|
|
||||||
- `warnings` (default `false`) — pass `true` to return compressor warnings
|
- `warnings` (default `false`) — pass `true` to return compressor warnings
|
||||||
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
|
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
|
||||||
|
|
||||||
@@ -464,7 +468,6 @@ if (result.error) throw result.error;
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
{
|
{
|
||||||
warnings: false,
|
|
||||||
parse: {
|
parse: {
|
||||||
// parse options
|
// parse options
|
||||||
},
|
},
|
||||||
@@ -484,8 +487,10 @@ if (result.error) throw result.error;
|
|||||||
sourceMap: {
|
sourceMap: {
|
||||||
// source map options
|
// source map options
|
||||||
},
|
},
|
||||||
|
ecma: 5, // specify one of: 5, 6, 7 or 8
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
|
warnings: false,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -539,6 +544,9 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
## Parse options
|
## Parse options
|
||||||
|
|
||||||
- `bare_returns` (default `false`) -- support top level `return` statements
|
- `bare_returns` (default `false`) -- support top level `return` statements
|
||||||
|
- `ecma` (default: `8`) -- specify one of `5`, `6`, `7` or `8`. Note: this setting
|
||||||
|
is not presently enforced except for ES8 optional trailing commas in function
|
||||||
|
parameter lists and calls with `ecma` `8`.
|
||||||
- `html5_comments` (default `true`)
|
- `html5_comments` (default `true`)
|
||||||
- `shebang` (default `true`) -- support `#!command` as the first line
|
- `shebang` (default `true`) -- support `#!command` as the first line
|
||||||
|
|
||||||
@@ -590,6 +598,10 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
|
|
||||||
- `evaluate` -- attempt to evaluate constant expressions
|
- `evaluate` -- attempt to evaluate constant expressions
|
||||||
|
|
||||||
|
- `arrows` (default `true`) -- convert ES5 style anonymous function expressions
|
||||||
|
to arrow functions if permissible by language semantics.
|
||||||
|
Note: `arrows` requires that the `ecma` compress option is set to `6` or greater.
|
||||||
|
|
||||||
- `booleans` -- various optimizations for boolean context, for example `!!a
|
- `booleans` -- various optimizations for boolean context, for example `!!a
|
||||||
? b : c → a ? b : c`
|
? b : c → a ? b : c`
|
||||||
|
|
||||||
@@ -678,6 +690,9 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
|
annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
|
||||||
example: `/*@__PURE__*/foo();`
|
example: `/*@__PURE__*/foo();`
|
||||||
|
|
||||||
|
- `ecma` -- default `5`. Pass `6` or greater to enable `compress` options that
|
||||||
|
will transform ES5 code into smaller ES6+ equivalent forms.
|
||||||
|
|
||||||
## Mangle options
|
## Mangle options
|
||||||
|
|
||||||
- `reserved` (default `[]`). Pass an array of identifiers that should be
|
- `reserved` (default `[]`). Pass an array of identifiers that should be
|
||||||
@@ -686,6 +701,8 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
- `toplevel` (default `false`). Pass `true` to mangle names declared in the
|
- `toplevel` (default `false`). Pass `true` to mangle names declared in the
|
||||||
top level scope.
|
top level scope.
|
||||||
|
|
||||||
|
- `keep_classnames` (default `false`). Pass `true` to not mangle class names.
|
||||||
|
|
||||||
- `keep_fnames` (default `false`). Pass `true` to not mangle function names.
|
- `keep_fnames` (default `false`). Pass `true` to not mangle function names.
|
||||||
Useful for code relying on `Function.prototype.name`. See also: the `keep_fnames`
|
Useful for code relying on `Function.prototype.name`. See also: the `keep_fnames`
|
||||||
[compress option](#compress-options).
|
[compress option](#compress-options).
|
||||||
@@ -749,9 +766,12 @@ can pass additional arguments that control the code output:
|
|||||||
- `comments` (default `false`) -- pass `true` or `"all"` to preserve all
|
- `comments` (default `false`) -- pass `true` or `"all"` to preserve all
|
||||||
comments, `"some"` to preserve some comments, a regular expression string
|
comments, `"some"` to preserve some comments, a regular expression string
|
||||||
(e.g. `/^!/`) or a function.
|
(e.g. `/^!/`) or a function.
|
||||||
- `ecma` (default `5`) -- set output printing mode. This will only change the
|
- `ecma` (default `5`) -- set output printing mode. Set `ecma` to `6` or
|
||||||
output in direct control of the beautifier. Non-compatible features in the
|
greater to emit shorthand object properties - i.e.: `{a}` instead of `{a: a}`.
|
||||||
abstract syntax tree will still be outputted as is.
|
The `ecma` option will only change the output in direct control of the
|
||||||
|
beautifier. Non-compatible features in the abstract syntax tree will still
|
||||||
|
be output as is. For example: an `ecma` setting of `5` will **not** convert
|
||||||
|
ES6+ code to ES5.
|
||||||
- `indent_level` (default 4)
|
- `indent_level` (default 4)
|
||||||
- `indent_start` (default 0) -- prefix all lines by that many spaces
|
- `indent_start` (default 0) -- prefix all lines by that many spaces
|
||||||
- `inline_script` (default `false`) -- escape the slash in occurrences of
|
- `inline_script` (default `false`) -- escape the slash in occurrences of
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ program.option("-o, --output <file>", "Output file (default STDOUT).");
|
|||||||
program.option("--comments [filter]", "Preserve copyright comments in the output.");
|
program.option("--comments [filter]", "Preserve copyright comments in the output.");
|
||||||
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
||||||
program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
|
program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
|
||||||
|
program.option("--ecma <version>", "Specifiy ECMAScript release: 5, 6, 7 or 8.");
|
||||||
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
||||||
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
||||||
program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
||||||
@@ -73,6 +74,10 @@ if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
|||||||
options[name] = program[name];
|
options[name] = program[name];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if ("ecma" in program) {
|
||||||
|
if (program.ecma != (program.ecma | 0)) fatal("ERROR: ecma must be an integer");
|
||||||
|
options.ecma = program.ecma | 0;
|
||||||
|
}
|
||||||
if (program.beautify) {
|
if (program.beautify) {
|
||||||
options.output = typeof program.beautify == "object" ? program.beautify : {};
|
options.output = typeof program.beautify == "object" ? program.beautify : {};
|
||||||
if (!("beautify" in options.output)) {
|
if (!("beautify" in options.output)) {
|
||||||
|
|||||||
@@ -345,7 +345,7 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
|||||||
var AST_Expansion = DEFNODE("Expansion", "expression", {
|
var AST_Expansion = DEFNODE("Expansion", "expression", {
|
||||||
$documentation: "An expandible argument, such as ...rest, a splat, such as [1,2,...all], or an expansion in a variable declaration, such as var [first, ...rest] = list",
|
$documentation: "An expandible argument, such as ...rest, a splat, such as [1,2,...all], or an expansion in a variable declaration, such as var [first, ...rest] = list",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "AST_Symbol the thing to be expanded"
|
expression: "[AST_Node] the thing to be expanded"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
var self = this;
|
var self = this;
|
||||||
@@ -446,7 +446,7 @@ var AST_PrefixedTemplateString = DEFNODE("PrefixedTemplateString", "template_str
|
|||||||
var AST_TemplateString = DEFNODE("TemplateString", "segments", {
|
var AST_TemplateString = DEFNODE("TemplateString", "segments", {
|
||||||
$documentation: "A template string literal",
|
$documentation: "A template string literal",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
segments: "[AST_TemplateSegment|AST_Expression]* One or more segments, starting with AST_TemplateSegment. AST_Expression may follow AST_TemplateSegment, but each AST_Expression must be followed by AST_TemplateSegment."
|
segments: "[AST_Node*] One or more segments, starting with AST_TemplateSegment. AST_Node may follow AST_TemplateSegment, but each AST_Node must be followed by AST_TemplateSegment."
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
return visitor._visit(this, function(){
|
return visitor._visit(this, function(){
|
||||||
|
|||||||
243
lib/compress.js
243
lib/compress.js
@@ -48,6 +48,7 @@ function Compressor(options, false_by_default) {
|
|||||||
return new Compressor(options, false_by_default);
|
return new Compressor(options, false_by_default);
|
||||||
TreeTransformer.call(this, this.before, this.after);
|
TreeTransformer.call(this, this.before, this.after);
|
||||||
this.options = defaults(options, {
|
this.options = defaults(options, {
|
||||||
|
arrows : !false_by_default,
|
||||||
booleans : !false_by_default,
|
booleans : !false_by_default,
|
||||||
cascade : !false_by_default,
|
cascade : !false_by_default,
|
||||||
collapse_vars : !false_by_default,
|
collapse_vars : !false_by_default,
|
||||||
@@ -93,12 +94,9 @@ function Compressor(options, false_by_default) {
|
|||||||
var global_defs = this.options["global_defs"];
|
var global_defs = this.options["global_defs"];
|
||||||
if (typeof global_defs == "object") for (var key in global_defs) {
|
if (typeof global_defs == "object") for (var key in global_defs) {
|
||||||
if (/^@/.test(key) && HOP(global_defs, key)) {
|
if (/^@/.test(key) && HOP(global_defs, key)) {
|
||||||
var ast = parse(global_defs[key]);
|
global_defs[key.slice(1)] = parse(global_defs[key], {
|
||||||
if (ast.body.length == 1 && ast.body[0] instanceof AST_SimpleStatement) {
|
expression: true
|
||||||
global_defs[key.slice(1)] = ast.body[0].body;
|
});
|
||||||
} else throw new Error(string_template("Can't handle expression: {value}", {
|
|
||||||
value: global_defs[key]
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var pure_funcs = this.options["pure_funcs"];
|
var pure_funcs = this.options["pure_funcs"];
|
||||||
@@ -125,15 +123,13 @@ function Compressor(options, false_by_default) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
var toplevel = this.options["toplevel"];
|
var toplevel = this.options["toplevel"];
|
||||||
if (typeof toplevel == "string") {
|
this.toplevel = typeof toplevel == "string" ? {
|
||||||
this.toplevel.funcs = /funcs/.test(toplevel);
|
funcs: /funcs/.test(toplevel),
|
||||||
this.toplevel.vars = /vars/.test(toplevel);
|
vars: /vars/.test(toplevel)
|
||||||
} else {
|
} : {
|
||||||
this.toplevel = toplevel ? function(def) {
|
funcs: toplevel,
|
||||||
return !def.export;
|
vars: toplevel
|
||||||
} : return_false;
|
};
|
||||||
this.toplevel.funcs = this.toplevel.vars = toplevel;
|
|
||||||
}
|
|
||||||
var sequences = this.options["sequences"];
|
var sequences = this.options["sequences"];
|
||||||
this.sequences_limit = sequences == 1 ? 800 : sequences | 0;
|
this.sequences_limit = sequences == 1 ? 800 : sequences | 0;
|
||||||
this.warnings_produced = {};
|
this.warnings_produced = {};
|
||||||
@@ -142,12 +138,12 @@ function Compressor(options, false_by_default) {
|
|||||||
Compressor.prototype = new TreeTransformer;
|
Compressor.prototype = new TreeTransformer;
|
||||||
merge(Compressor.prototype, {
|
merge(Compressor.prototype, {
|
||||||
option: function(key) { return this.options[key] },
|
option: function(key) { return this.options[key] },
|
||||||
toplevel: function(def) {
|
exposed: function(def) {
|
||||||
if (def.export) return false;
|
if (def.export) return true;
|
||||||
for (var i = 0, len = def.orig.length; i < len; i++)
|
if (def.global) for (var i = 0, len = def.orig.length; i < len; i++)
|
||||||
if (!this.toplevel[def.orig[i] instanceof AST_SymbolDefun ? "funcs" : "vars"])
|
if (!this.toplevel[def.orig[i] instanceof AST_SymbolDefun ? "funcs" : "vars"])
|
||||||
return false;
|
return true;
|
||||||
return true;
|
return false;
|
||||||
},
|
},
|
||||||
compress: function(node) {
|
compress: function(node) {
|
||||||
if (this.option("expression")) {
|
if (this.option("expression")) {
|
||||||
@@ -283,11 +279,11 @@ merge(Compressor.prototype, {
|
|||||||
var reduce_vars = rescan && compressor.option("reduce_vars");
|
var reduce_vars = rescan && compressor.option("reduce_vars");
|
||||||
var safe_ids = Object.create(null);
|
var safe_ids = Object.create(null);
|
||||||
var suppressor = new TreeWalker(function(node) {
|
var suppressor = new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_Symbol) {
|
if (!(node instanceof AST_Symbol)) return;
|
||||||
var d = node.definition();
|
var d = node.definition();
|
||||||
if (node instanceof AST_SymbolRef) d.references.push(node);
|
if (!d) return;
|
||||||
d.fixed = false;
|
if (node instanceof AST_SymbolRef) d.references.push(node);
|
||||||
}
|
d.fixed = false;
|
||||||
});
|
});
|
||||||
var tw = new TreeWalker(function(node, descend) {
|
var tw = new TreeWalker(function(node, descend) {
|
||||||
node._squeezed = false;
|
node._squeezed = false;
|
||||||
@@ -355,7 +351,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
if (node instanceof AST_Defun) {
|
if (node instanceof AST_Defun) {
|
||||||
var d = node.name.definition();
|
var d = node.name.definition();
|
||||||
if (d.global && !compressor.toplevel(d) || safe_to_read(d)) {
|
if (compressor.exposed(d) || safe_to_read(d)) {
|
||||||
d.fixed = false;
|
d.fixed = false;
|
||||||
} else {
|
} else {
|
||||||
d.fixed = node;
|
d.fixed = node;
|
||||||
@@ -367,7 +363,7 @@ merge(Compressor.prototype, {
|
|||||||
safe_ids = save_ids;
|
safe_ids = save_ids;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Function || node instanceof AST_Arrow) {
|
if (is_func_expr(node)) {
|
||||||
push();
|
push();
|
||||||
var iife;
|
var iife;
|
||||||
if (!node.name
|
if (!node.name
|
||||||
@@ -530,7 +526,7 @@ merge(Compressor.prototype, {
|
|||||||
def.escaped = false;
|
def.escaped = false;
|
||||||
if (def.scope.uses_eval) {
|
if (def.scope.uses_eval) {
|
||||||
def.fixed = false;
|
def.fixed = false;
|
||||||
} else if (!def.global || def.orig[0] instanceof AST_SymbolConst || compressor.toplevel(def)) {
|
} else if (def.orig[0] instanceof AST_SymbolConst || !compressor.exposed(def)) {
|
||||||
def.fixed = undefined;
|
def.fixed = undefined;
|
||||||
} else {
|
} else {
|
||||||
def.fixed = false;
|
def.fixed = false;
|
||||||
@@ -560,8 +556,29 @@ merge(Compressor.prototype, {
|
|||||||
return fixed();
|
return fixed();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AST_SymbolRef.DEFMETHOD("is_immutable", function() {
|
||||||
|
var orig = this.definition().orig;
|
||||||
|
return orig.length == 1 && orig[0] instanceof AST_SymbolLambda;
|
||||||
|
});
|
||||||
|
|
||||||
|
function is_func_expr(node) {
|
||||||
|
return node instanceof AST_Arrow || node instanceof AST_Function;
|
||||||
|
}
|
||||||
|
|
||||||
function is_lhs_read_only(lhs) {
|
function is_lhs_read_only(lhs) {
|
||||||
return lhs instanceof AST_SymbolRef && lhs.definition().orig[0] instanceof AST_SymbolLambda;
|
if (lhs instanceof AST_SymbolRef) return lhs.definition().orig[0] instanceof AST_SymbolLambda;
|
||||||
|
if (lhs instanceof AST_PropAccess) {
|
||||||
|
lhs = lhs.expression;
|
||||||
|
if (lhs instanceof AST_SymbolRef) {
|
||||||
|
if (lhs.is_immutable()) return false;
|
||||||
|
lhs = lhs.fixed_value();
|
||||||
|
}
|
||||||
|
if (!lhs) return true;
|
||||||
|
if (lhs instanceof AST_RegExp) return false;
|
||||||
|
if (lhs instanceof AST_Constant) return true;
|
||||||
|
return is_lhs_read_only(lhs);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function is_ref_of(ref, type) {
|
function is_ref_of(ref, type) {
|
||||||
@@ -691,7 +708,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
function is_iife_call(node) {
|
function is_iife_call(node) {
|
||||||
if (node instanceof AST_Call && !(node instanceof AST_New)) {
|
if (node instanceof AST_Call && !(node instanceof AST_New)) {
|
||||||
return node.expression instanceof AST_Function || is_iife_call(node.expression);
|
return is_func_expr(node.expression) || is_iife_call(node.expression);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -782,7 +799,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
if (candidate instanceof AST_VarDef) {
|
if (candidate instanceof AST_VarDef) {
|
||||||
var def = candidate.name.definition();
|
var def = candidate.name.definition();
|
||||||
if (def.references.length == 1 && (!def.global || compressor.toplevel(def))) {
|
if (def.references.length == 1 && !compressor.exposed(def)) {
|
||||||
return maintain_this_binding(parent, node, candidate.value);
|
return maintain_this_binding(parent, node, candidate.value);
|
||||||
}
|
}
|
||||||
return make_node(AST_Assign, candidate, {
|
return make_node(AST_Assign, candidate, {
|
||||||
@@ -844,7 +861,7 @@ merge(Compressor.prototype, {
|
|||||||
if (expr instanceof AST_VarDef && expr.name instanceof AST_SymbolDeclaration) {
|
if (expr instanceof AST_VarDef && expr.name instanceof AST_SymbolDeclaration) {
|
||||||
var def = expr.name.definition();
|
var def = expr.name.definition();
|
||||||
if (def.orig.length > 1
|
if (def.orig.length > 1
|
||||||
|| def.references.length == 1 && (!def.global || compressor.toplevel(def))) {
|
|| def.references.length == 1 && !compressor.exposed(def)) {
|
||||||
return make_node(AST_SymbolRef, expr.name, expr.name);
|
return make_node(AST_SymbolRef, expr.name, expr.name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1304,6 +1321,7 @@ merge(Compressor.prototype, {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
def(AST_Function, return_false);
|
def(AST_Function, return_false);
|
||||||
|
def(AST_Arrow, return_false);
|
||||||
def(AST_UnaryPostfix, return_false);
|
def(AST_UnaryPostfix, return_false);
|
||||||
def(AST_UnaryPrefix, function() {
|
def(AST_UnaryPrefix, function() {
|
||||||
return this.operator == "void";
|
return this.operator == "void";
|
||||||
@@ -1333,6 +1351,7 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_SymbolRef, function(pure_getters) {
|
def(AST_SymbolRef, function(pure_getters) {
|
||||||
if (this.is_undefined) return true;
|
if (this.is_undefined) return true;
|
||||||
if (!is_strict(pure_getters)) return false;
|
if (!is_strict(pure_getters)) return false;
|
||||||
|
if (this.is_immutable()) return false;
|
||||||
var fixed = this.fixed_value();
|
var fixed = this.fixed_value();
|
||||||
return !fixed || fixed._throw_on_access(pure_getters);
|
return !fixed || fixed._throw_on_access(pure_getters);
|
||||||
});
|
});
|
||||||
@@ -1576,9 +1595,6 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_Lambda, function(){
|
def(AST_Lambda, function(){
|
||||||
throw def;
|
throw def;
|
||||||
});
|
});
|
||||||
def(AST_Arrow, function() {
|
|
||||||
throw def;
|
|
||||||
});
|
|
||||||
def(AST_Class, function() {
|
def(AST_Class, function() {
|
||||||
throw def;
|
throw def;
|
||||||
});
|
});
|
||||||
@@ -1632,8 +1648,7 @@ merge(Compressor.prototype, {
|
|||||||
case "typeof":
|
case "typeof":
|
||||||
// Function would be evaluated to an array and so typeof would
|
// Function would be evaluated to an array and so typeof would
|
||||||
// incorrectly return 'object'. Hence making is a special case.
|
// incorrectly return 'object'. Hence making is a special case.
|
||||||
if (e instanceof AST_Function ||
|
if (is_func_expr(e)) return typeof function(){};
|
||||||
e instanceof AST_Arrow) return typeof function(){};
|
|
||||||
|
|
||||||
e = ev(e, compressor);
|
e = ev(e, compressor);
|
||||||
|
|
||||||
@@ -1805,6 +1820,9 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_Function, function(){
|
def(AST_Function, function(){
|
||||||
return basic_negation(this);
|
return basic_negation(this);
|
||||||
});
|
});
|
||||||
|
def(AST_Arrow, function(){
|
||||||
|
return basic_negation(this);
|
||||||
|
});
|
||||||
def(AST_UnaryPrefix, function(){
|
def(AST_UnaryPrefix, function(){
|
||||||
if (this.operator == "!")
|
if (this.operator == "!")
|
||||||
return this.expression;
|
return this.expression;
|
||||||
@@ -2047,7 +2065,7 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_Block, function(self, compressor){
|
OPT(AST_Block, function(self, compressor){
|
||||||
if (!(self.body instanceof AST_Node)) tighten_body(self.body, compressor);
|
tighten_body(self.body, compressor);
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2086,7 +2104,6 @@ merge(Compressor.prototype, {
|
|||||||
var var_defs_by_id = new Dictionary();
|
var var_defs_by_id = new Dictionary();
|
||||||
var initializations = new Dictionary();
|
var initializations = new Dictionary();
|
||||||
var destructuring_value = null;
|
var destructuring_value = null;
|
||||||
var in_definition = false;
|
|
||||||
// pass 1: find out which symbols are directly used in
|
// pass 1: find out which symbols are directly used in
|
||||||
// this scope (not in nested scopes).
|
// this scope (not in nested scopes).
|
||||||
var scope = this;
|
var scope = this;
|
||||||
@@ -2125,9 +2142,7 @@ merge(Compressor.prototype, {
|
|||||||
if (def.name instanceof AST_Destructuring) {
|
if (def.name instanceof AST_Destructuring) {
|
||||||
var destructuring_cache = destructuring_value;
|
var destructuring_cache = destructuring_value;
|
||||||
destructuring_value = def.value;
|
destructuring_value = def.value;
|
||||||
in_definition = true;
|
|
||||||
def.walk(tw);
|
def.walk(tw);
|
||||||
in_definition = false;
|
|
||||||
destructuring_value = destructuring_cache;
|
destructuring_value = destructuring_cache;
|
||||||
} else {
|
} else {
|
||||||
initializations.add(def.name.name, def.value);
|
initializations.add(def.name.name, def.value);
|
||||||
@@ -2163,46 +2178,8 @@ merge(Compressor.prototype, {
|
|||||||
scope = save_scope;
|
scope = save_scope;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Destructuring) {
|
if (node.destructuring && destructuring_value) {
|
||||||
if (!in_definition) {
|
initializations.add(node.name, destructuring_value);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for (var i = 0; i < node.names.length; i++) {
|
|
||||||
if (node.names[i] instanceof AST_Destructuring) {
|
|
||||||
node.names[i].walk(tw);
|
|
||||||
}
|
|
||||||
else if (node.names[i] instanceof AST_Expansion) {
|
|
||||||
if (node.names[i].expression instanceof AST_Symbol) {
|
|
||||||
initializations.add(node.names[i].expression.name, destructuring_value);
|
|
||||||
} else if (node.names[i].expression instanceof AST_Destructuring) {
|
|
||||||
node.names[i].expression.walk(tw);
|
|
||||||
} else {
|
|
||||||
throw new Error(string_template("Can't handle expansion of type: {type}", {
|
|
||||||
type: Object.getPrototypeOf(node.names[i].expression).TYPE
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (node.names[i] instanceof AST_ObjectKeyVal) {
|
|
||||||
if (typeof node.names[i].key === "string") {
|
|
||||||
initializations.add(node.names[i].key, destructuring_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (node.names[i] instanceof AST_Symbol) {
|
|
||||||
initializations.add(node.names[i].name, destructuring_value);
|
|
||||||
}
|
|
||||||
else if (node.names[i] instanceof AST_DefaultAssign) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (node.names[i] instanceof AST_Hole) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error(string_template("Unknown destructuring element of type: {type}", {
|
|
||||||
type: Object.getPrototypeOf(node.names[i]).TYPE
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -2592,7 +2569,7 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_This, return_null);
|
def(AST_This, return_null);
|
||||||
def(AST_Call, function(compressor, first_in_statement){
|
def(AST_Call, function(compressor, first_in_statement){
|
||||||
if (!this.has_pure_annotation(compressor) && compressor.pure_funcs(this)) {
|
if (!this.has_pure_annotation(compressor) && compressor.pure_funcs(this)) {
|
||||||
if (this.expression instanceof AST_Function
|
if (is_func_expr(this.expression)
|
||||||
&& (!this.expression.name || !this.expression.name.definition().references.length)) {
|
&& (!this.expression.name || !this.expression.name.definition().references.length)) {
|
||||||
var node = this.clone();
|
var node = this.clone();
|
||||||
node.expression.process_expression(false, compressor);
|
node.expression.process_expression(false, compressor);
|
||||||
@@ -2696,6 +2673,9 @@ merge(Compressor.prototype, {
|
|||||||
if (expr) merge_sequence(expressions, expr);
|
if (expr) merge_sequence(expressions, expr);
|
||||||
return make_sequence(this, expressions);
|
return make_sequence(this, expressions);
|
||||||
});
|
});
|
||||||
|
def(AST_Expansion, function(compressor, first_in_statement){
|
||||||
|
return this.expression.drop_side_effect_free(compressor, first_in_statement);
|
||||||
|
});
|
||||||
})(function(node, func){
|
})(function(node, func){
|
||||||
node.DEFMETHOD("drop_side_effect_free", func);
|
node.DEFMETHOD("drop_side_effect_free", func);
|
||||||
});
|
});
|
||||||
@@ -3116,10 +3096,10 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
if (compressor.option("unused")
|
if (compressor.option("unused")
|
||||||
&& simple_args
|
&& simple_args
|
||||||
&& (fn instanceof AST_Function
|
&& (is_func_expr(fn)
|
||||||
|| compressor.option("reduce_vars")
|
|| compressor.option("reduce_vars")
|
||||||
&& fn instanceof AST_SymbolRef
|
&& fn instanceof AST_SymbolRef
|
||||||
&& (fn = fn.fixed_value()) instanceof AST_Function)
|
&& is_func_expr(fn = fn.fixed_value()))
|
||||||
&& !fn.uses_arguments
|
&& !fn.uses_arguments
|
||||||
&& !fn.uses_eval) {
|
&& !fn.uses_eval) {
|
||||||
var pos = 0, last = 0;
|
var pos = 0, last = 0;
|
||||||
@@ -3293,7 +3273,7 @@ merge(Compressor.prototype, {
|
|||||||
if (self.args.length == 0) return make_node(AST_Function, self, {
|
if (self.args.length == 0) return make_node(AST_Function, self, {
|
||||||
argnames: [],
|
argnames: [],
|
||||||
body: []
|
body: []
|
||||||
});
|
}).optimize(compressor);
|
||||||
if (all(self.args, function(x) {
|
if (all(self.args, function(x) {
|
||||||
return x instanceof AST_String;
|
return x instanceof AST_String;
|
||||||
})) {
|
})) {
|
||||||
@@ -3301,7 +3281,7 @@ merge(Compressor.prototype, {
|
|||||||
// https://github.com/mishoo/UglifyJS2/issues/203
|
// https://github.com/mishoo/UglifyJS2/issues/203
|
||||||
// if the code argument is a constant, then we can minify it.
|
// if the code argument is a constant, then we can minify it.
|
||||||
try {
|
try {
|
||||||
var code = "NaN(function(" + self.args.slice(0, -1).map(function(arg) {
|
var code = "n(function(" + self.args.slice(0, -1).map(function(arg) {
|
||||||
return arg.value;
|
return arg.value;
|
||||||
}).join(",") + "){" + self.args[self.args.length - 1].value + "})";
|
}).join(",") + "){" + self.args[self.args.length - 1].value + "})";
|
||||||
var ast = parse(code);
|
var ast = parse(code);
|
||||||
@@ -3310,27 +3290,36 @@ merge(Compressor.prototype, {
|
|||||||
var comp = new Compressor(compressor.options);
|
var comp = new Compressor(compressor.options);
|
||||||
ast = ast.transform(comp);
|
ast = ast.transform(comp);
|
||||||
ast.figure_out_scope(mangle);
|
ast.figure_out_scope(mangle);
|
||||||
ast.mangle_names();
|
base54.reset();
|
||||||
|
ast.compute_char_frequency(mangle);
|
||||||
|
ast.mangle_names(mangle);
|
||||||
var fun;
|
var fun;
|
||||||
ast.walk(new TreeWalker(function(node) {
|
ast.walk(new TreeWalker(function(node) {
|
||||||
if (fun) return true;
|
if (fun) return true;
|
||||||
if (node instanceof AST_Lambda) {
|
if (is_func_expr(node)) {
|
||||||
fun = node;
|
fun = node;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
var args = fun.argnames.map(function(arg, i) {
|
if (fun.body instanceof AST_Node) {
|
||||||
return make_node(AST_String, self.args[i], {
|
fun.body = [
|
||||||
value: arg.print_to_string()
|
make_node(AST_Return, fun.body, {
|
||||||
});
|
value: fun.body
|
||||||
});
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
var code = OutputStream();
|
var code = OutputStream();
|
||||||
AST_BlockStatement.prototype._codegen.call(fun, fun, code);
|
AST_BlockStatement.prototype._codegen.call(fun, fun, code);
|
||||||
code = code.toString().replace(/^\{|\}$/g, "");
|
self.args = [
|
||||||
args.push(make_node(AST_String, self.args[self.args.length - 1], {
|
make_node(AST_String, self, {
|
||||||
value: code
|
value: fun.argnames.map(function(arg) {
|
||||||
}));
|
return arg.print_to_string();
|
||||||
self.args = args;
|
}).join(",")
|
||||||
|
}),
|
||||||
|
make_node(AST_String, self.args[self.args.length - 1], {
|
||||||
|
value: code.get().replace(/^\{|\}$/g, "")
|
||||||
|
})
|
||||||
|
];
|
||||||
return self;
|
return self;
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
if (ex instanceof JS_Parse_Error) {
|
if (ex instanceof JS_Parse_Error) {
|
||||||
@@ -3342,7 +3331,14 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var stat = fn instanceof AST_Function && fn.body[0];
|
var stat = is_func_expr(fn) && fn.body;
|
||||||
|
if (stat instanceof AST_Node) {
|
||||||
|
stat = make_node(AST_Return, stat, {
|
||||||
|
value: stat
|
||||||
|
});
|
||||||
|
} else if (stat) {
|
||||||
|
stat = stat[0];
|
||||||
|
}
|
||||||
if (compressor.option("inline") && stat instanceof AST_Return) {
|
if (compressor.option("inline") && stat instanceof AST_Return) {
|
||||||
var value = stat.value;
|
var value = stat.value;
|
||||||
if (!value || value.is_constant_expression()) {
|
if (!value || value.is_constant_expression()) {
|
||||||
@@ -3350,10 +3346,10 @@ merge(Compressor.prototype, {
|
|||||||
return make_sequence(self, args).transform(compressor);
|
return make_sequence(self, args).transform(compressor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (exp instanceof AST_Function && !exp.is_generator && !exp.async) {
|
if (is_func_expr(exp) && !exp.is_generator && !exp.async) {
|
||||||
if (compressor.option("inline")
|
if (compressor.option("inline")
|
||||||
&& !exp.name
|
&& !exp.name
|
||||||
&& exp.body.length == 1
|
&& (exp.body instanceof AST_Node || exp.body.length == 1)
|
||||||
&& !exp.uses_arguments
|
&& !exp.uses_arguments
|
||||||
&& !exp.uses_eval
|
&& !exp.uses_eval
|
||||||
&& simple_args
|
&& simple_args
|
||||||
@@ -3403,6 +3399,13 @@ merge(Compressor.prototype, {
|
|||||||
value: value
|
value: value
|
||||||
}));
|
}));
|
||||||
var body = fn.transform(compressor).body;
|
var body = fn.transform(compressor).body;
|
||||||
|
if (body instanceof AST_Node) {
|
||||||
|
body = [
|
||||||
|
make_node(AST_Return, body, {
|
||||||
|
value: body
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
if (body.length == 0) return make_node(AST_Undefined, self);
|
if (body.length == 0) return make_node(AST_Undefined, self);
|
||||||
if (body.length == 1 && body[0] instanceof AST_Return) {
|
if (body.length == 1 && body[0] instanceof AST_Return) {
|
||||||
value = body[0].value;
|
value = body[0].value;
|
||||||
@@ -3429,7 +3432,7 @@ merge(Compressor.prototype, {
|
|||||||
if (value !== self) return value;
|
if (value !== self) return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compressor.option("side_effects") && all(exp.body, is_empty)) {
|
if (compressor.option("side_effects") && !(exp.body instanceof AST_Node) && all(exp.body, is_empty)) {
|
||||||
var args = self.args.concat(make_node(AST_Undefined, self));
|
var args = self.args.concat(make_node(AST_Undefined, self));
|
||||||
return make_sequence(self, args).transform(compressor);
|
return make_sequence(self, args).transform(compressor);
|
||||||
}
|
}
|
||||||
@@ -3564,6 +3567,8 @@ merge(Compressor.prototype, {
|
|||||||
|| cdr instanceof AST_PropAccess
|
|| cdr instanceof AST_PropAccess
|
||||||
|| cdr instanceof AST_Unary && !unary_side_effects(cdr.operator)) {
|
|| cdr instanceof AST_Unary && !unary_side_effects(cdr.operator)) {
|
||||||
field = "expression";
|
field = "expression";
|
||||||
|
} else if (cdr instanceof AST_Conditional) {
|
||||||
|
field = "condition";
|
||||||
} else {
|
} else {
|
||||||
expressions[++i] = expressions[j];
|
expressions[++i] = expressions[j];
|
||||||
break;
|
break;
|
||||||
@@ -4098,15 +4103,15 @@ merge(Compressor.prototype, {
|
|||||||
var d = self.definition();
|
var d = self.definition();
|
||||||
var fixed = self.fixed_value();
|
var fixed = self.fixed_value();
|
||||||
if (fixed instanceof AST_Defun) {
|
if (fixed instanceof AST_Defun) {
|
||||||
d.fixed = fixed = make_node(AST_Function, fixed, fixed).clone(true);
|
d.fixed = fixed = make_node(AST_Function, fixed, fixed);
|
||||||
}
|
}
|
||||||
if (compressor.option("unused")
|
if (compressor.option("unused")
|
||||||
&& fixed instanceof AST_Function
|
&& is_func_expr(fixed)
|
||||||
&& d.references.length == 1
|
&& d.references.length == 1
|
||||||
&& !(d.scope.uses_arguments && d.orig[0] instanceof AST_SymbolFunarg)
|
&& !(d.scope.uses_arguments && d.orig[0] instanceof AST_SymbolFunarg)
|
||||||
&& !d.scope.uses_eval
|
&& !d.scope.uses_eval
|
||||||
&& compressor.find_parent(AST_Scope) === fixed.parent_scope) {
|
&& compressor.find_parent(AST_Scope) === fixed.parent_scope) {
|
||||||
return fixed;
|
return fixed.clone(true);
|
||||||
}
|
}
|
||||||
if (compressor.option("evaluate") && fixed) {
|
if (compressor.option("evaluate") && fixed) {
|
||||||
if (d.should_replace === undefined) {
|
if (d.should_replace === undefined) {
|
||||||
@@ -4129,7 +4134,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
var name_length = d.name.length;
|
var name_length = d.name.length;
|
||||||
var overhead = 0;
|
var overhead = 0;
|
||||||
if (compressor.option("unused") && (!d.global || compressor.toplevel(d))) {
|
if (compressor.option("unused") && !compressor.exposed(d)) {
|
||||||
overhead = (name_length + 2 + value_length) / d.references.length;
|
overhead = (name_length + 2 + value_length) / d.references.length;
|
||||||
}
|
}
|
||||||
d.should_replace = value_length <= name_length + overhead ? fn : false;
|
d.should_replace = value_length <= name_length + overhead ? fn : false;
|
||||||
@@ -4540,13 +4545,37 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_Arrow, function(self, compressor){
|
OPT(AST_Arrow, function(self, compressor){
|
||||||
if (self.body.length === 1 && self.body[0] instanceof AST_Return) {
|
if (!(self.body instanceof AST_Node)) tighten_body(self.body, compressor);
|
||||||
|
if (compressor.option("arrows")
|
||||||
|
&& self.body.length == 1
|
||||||
|
&& self.body[0] instanceof AST_Return) {
|
||||||
var value = self.body[0].value;
|
var value = self.body[0].value;
|
||||||
self.body = value ? value : [];
|
self.body = value ? value : [];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
OPT(AST_Function, function(self, compressor){
|
||||||
|
tighten_body(self.body, compressor);
|
||||||
|
if (compressor.option("arrows")
|
||||||
|
&& compressor.option("ecma") >= 6
|
||||||
|
&& !self.name
|
||||||
|
&& !self.is_generator
|
||||||
|
&& !self.uses_arguments
|
||||||
|
&& !self.uses_eval) {
|
||||||
|
var has_special_symbol = false;
|
||||||
|
self.walk(new TreeWalker(function(node) {
|
||||||
|
if (has_special_symbol) return true;
|
||||||
|
if (node instanceof AST_Symbol && !node.definition()) {
|
||||||
|
has_special_symbol = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
if (!has_special_symbol) return make_node(AST_Arrow, self, self).optimize(compressor);
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
});
|
||||||
|
|
||||||
OPT(AST_Class, function(self, compressor){
|
OPT(AST_Class, function(self, compressor){
|
||||||
// HACK to avoid compress failure.
|
// HACK to avoid compress failure.
|
||||||
// AST_Class is not really an AST_Scope/AST_Block as it lacks a body.
|
// AST_Class is not really an AST_Scope/AST_Block as it lacks a body.
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ function minify(files, options) {
|
|||||||
try {
|
try {
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
compress: {},
|
compress: {},
|
||||||
|
ecma: undefined,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
keep_fnames: false,
|
keep_fnames: false,
|
||||||
mangle: {},
|
mangle: {},
|
||||||
@@ -46,6 +47,7 @@ function minify(files, options) {
|
|||||||
var timings = options.timings && {
|
var timings = options.timings && {
|
||||||
start: Date.now()
|
start: Date.now()
|
||||||
};
|
};
|
||||||
|
set_shorthand("ecma", options, [ "parse", "compress", "output" ]);
|
||||||
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
||||||
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||||
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||||
|
|||||||
@@ -533,6 +533,7 @@ function OutputStream(options) {
|
|||||||
use_asm = prev_use_asm;
|
use_asm = prev_use_asm;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
AST_Node.DEFMETHOD("_print", AST_Node.prototype.print);
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("print_to_string", function(options){
|
AST_Node.DEFMETHOD("print_to_string", function(options){
|
||||||
var s = OutputStream(options);
|
var s = OutputStream(options);
|
||||||
@@ -978,12 +979,12 @@ function OutputStream(options) {
|
|||||||
AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword){
|
AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword){
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!nokeyword) {
|
if (!nokeyword) {
|
||||||
if (this.async) {
|
if (self.async) {
|
||||||
output.print("async");
|
output.print("async");
|
||||||
output.space();
|
output.space();
|
||||||
}
|
}
|
||||||
output.print("function");
|
output.print("function");
|
||||||
if (this.is_generator) {
|
if (self.is_generator) {
|
||||||
output.star();
|
output.star();
|
||||||
}
|
}
|
||||||
if (self.name) {
|
if (self.name) {
|
||||||
@@ -1038,6 +1039,10 @@ function OutputStream(options) {
|
|||||||
var needs_parens = parent instanceof AST_Binary ||
|
var needs_parens = parent instanceof AST_Binary ||
|
||||||
parent instanceof AST_Unary ||
|
parent instanceof AST_Unary ||
|
||||||
(parent instanceof AST_Call && self === parent.expression);
|
(parent instanceof AST_Call && self === parent.expression);
|
||||||
|
if (self.async) {
|
||||||
|
output.print("async");
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
if (needs_parens) { output.print("(") }
|
if (needs_parens) { output.print("(") }
|
||||||
if (self.argnames.length === 1 && self.argnames[0] instanceof AST_Symbol) {
|
if (self.argnames.length === 1 && self.argnames[0] instanceof AST_Symbol) {
|
||||||
self.argnames[0].print(output);
|
self.argnames[0].print(output);
|
||||||
@@ -1053,9 +1058,9 @@ function OutputStream(options) {
|
|||||||
output.print('=>');
|
output.print('=>');
|
||||||
output.space();
|
output.space();
|
||||||
if (self.body instanceof AST_Node) {
|
if (self.body instanceof AST_Node) {
|
||||||
this.body.print(output);
|
self.body.print(output);
|
||||||
} else {
|
} else {
|
||||||
print_bracketed(this.body, output);
|
print_bracketed(self.body, output);
|
||||||
}
|
}
|
||||||
if (needs_parens) { output.print(")") }
|
if (needs_parens) { output.print(")") }
|
||||||
});
|
});
|
||||||
|
|||||||
151
lib/parse.js
151
lib/parse.js
@@ -509,8 +509,11 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
}
|
}
|
||||||
var content = "", raw = "", ch, tok;
|
var content = "", raw = "", ch, tok;
|
||||||
next(true, true);
|
next(true, true);
|
||||||
while ((ch = next(true, true)) !== "`") {
|
while ((ch = next(true, true)) != "`") {
|
||||||
if (ch === "$" && peek() === "{") {
|
if (ch == "\r") {
|
||||||
|
if (peek() == "\n") ++S.pos;
|
||||||
|
ch = "\n";
|
||||||
|
} else if (ch == "$" && peek() == "{") {
|
||||||
next(true, true);
|
next(true, true);
|
||||||
S.brace_counter++;
|
S.brace_counter++;
|
||||||
tok = token(begin ? "template_head" : "template_substitution", content);
|
tok = token(begin ? "template_head" : "template_substitution", content);
|
||||||
@@ -521,7 +524,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
raw += ch;
|
raw += ch;
|
||||||
if (ch === "\\") {
|
if (ch == "\\") {
|
||||||
var tmp = S.pos;
|
var tmp = S.pos;
|
||||||
ch = read_escaped_char();
|
ch = read_escaped_char();
|
||||||
raw += S.text.substr(tmp, S.pos - tmp);
|
raw += S.text.substr(tmp, S.pos - tmp);
|
||||||
@@ -856,6 +859,7 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
bare_returns : false,
|
bare_returns : false,
|
||||||
|
ecma : 8,
|
||||||
expression : false,
|
expression : false,
|
||||||
filename : null,
|
filename : null,
|
||||||
html5_comments : true,
|
html5_comments : true,
|
||||||
@@ -1229,9 +1233,12 @@ function parse($TEXT, options) {
|
|||||||
var is_in = is("operator", "in");
|
var is_in = is("operator", "in");
|
||||||
var is_of = is("name", "of");
|
var is_of = is("name", "of");
|
||||||
if (is_in || is_of) {
|
if (is_in || is_of) {
|
||||||
if ((init instanceof AST_Definitions) &&
|
if (init instanceof AST_Definitions) {
|
||||||
init.definitions.length > 1)
|
if (init.definitions.length > 1)
|
||||||
croak("Only one variable declaration allowed in for..in loop");
|
croak("Only one variable declaration allowed in for..in loop", init.start.line, init.start.col, init.start.pos);
|
||||||
|
} else if (!(is_assignable(init) || (init = to_destructuring(init)) instanceof AST_Destructuring)) {
|
||||||
|
croak("Invalid left-hand side in for..in loop", init.start.line, init.start.col, init.start.pos);
|
||||||
|
}
|
||||||
next();
|
next();
|
||||||
if (is_in) {
|
if (is_in) {
|
||||||
return for_in(init);
|
return for_in(init);
|
||||||
@@ -1281,18 +1288,19 @@ function parse($TEXT, options) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var arrow_function = function(start, argnames) {
|
var arrow_function = function(start, argnames, is_async) {
|
||||||
if (S.token.nlb) {
|
if (S.token.nlb) {
|
||||||
croak("Unexpected newline before arrow (=>)");
|
croak("Unexpected newline before arrow (=>)");
|
||||||
}
|
}
|
||||||
|
|
||||||
expect_token("arrow", "=>");
|
expect_token("arrow", "=>");
|
||||||
|
|
||||||
var body = _function_body(is("punc", "{"));
|
var body = _function_body(is("punc", "{"), false, is_async);
|
||||||
|
|
||||||
return new AST_Arrow({
|
return new AST_Arrow({
|
||||||
start : start,
|
start : start,
|
||||||
end : body.end,
|
end : body.end,
|
||||||
|
async : is_async,
|
||||||
argnames : argnames,
|
argnames : argnames,
|
||||||
body : body
|
body : body
|
||||||
});
|
});
|
||||||
@@ -1385,22 +1393,20 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
function parameters() {
|
function parameters() {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
var first = true;
|
|
||||||
var params = [];
|
var params = [];
|
||||||
var used_parameters = track_used_binding_identifiers(true, S.input.has_directive("use strict"));
|
var used_parameters = track_used_binding_identifiers(true, S.input.has_directive("use strict"));
|
||||||
|
|
||||||
expect("(");
|
expect("(");
|
||||||
|
|
||||||
while (!is("punc", ")")) {
|
while (!is("punc", ")")) {
|
||||||
if (first) {
|
|
||||||
first = false;
|
|
||||||
} else {
|
|
||||||
expect(",");
|
|
||||||
}
|
|
||||||
|
|
||||||
var param = parameter(used_parameters);
|
var param = parameter(used_parameters);
|
||||||
params.push(param);
|
params.push(param);
|
||||||
|
|
||||||
|
if (!is("punc", ")")) {
|
||||||
|
expect(",");
|
||||||
|
if (is("punc", ")") && options.ecma < 8) unexpected();
|
||||||
|
}
|
||||||
|
|
||||||
if (param instanceof AST_Expansion) {
|
if (param instanceof AST_Expansion) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1616,25 +1622,40 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function params_or_seq_() {
|
function params_or_seq_(allow_arrows, maybe_sequence) {
|
||||||
var first = true;
|
var spread_token;
|
||||||
|
var invalid_sequence;
|
||||||
|
var trailing_comma;
|
||||||
var a = [];
|
var a = [];
|
||||||
|
expect("(");
|
||||||
while (!is("punc", ")")) {
|
while (!is("punc", ")")) {
|
||||||
if (first) first = false; else expect(",");
|
if (spread_token) unexpected(spread_token);
|
||||||
if (is("expand", "...")) {
|
if (is("expand", "...")) {
|
||||||
var spread_token = S.token;
|
spread_token = S.token;
|
||||||
|
if (maybe_sequence) invalid_sequence = S.token;
|
||||||
next();
|
next();
|
||||||
a.push(new AST_Expansion({
|
a.push(new AST_Expansion({
|
||||||
start: prev(),
|
start: prev(),
|
||||||
expression: expression(),
|
expression: expression(),
|
||||||
end: S.token,
|
end: S.token,
|
||||||
}));
|
}));
|
||||||
if (!is("punc", ")")) {
|
|
||||||
unexpected(spread_token);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
a.push(expression());
|
a.push(expression());
|
||||||
}
|
}
|
||||||
|
if (!is("punc", ")")) {
|
||||||
|
expect(",");
|
||||||
|
if (is("punc", ")")) {
|
||||||
|
if (options.ecma < 8) unexpected();
|
||||||
|
trailing_comma = prev();
|
||||||
|
if (maybe_sequence) invalid_sequence = trailing_comma;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(")");
|
||||||
|
if (allow_arrows && is("arrow", "=>")) {
|
||||||
|
if (spread_token && trailing_comma) unexpected(trailing_comma);
|
||||||
|
} else if (invalid_sequence) {
|
||||||
|
unexpected(invalid_sequence);
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
@@ -1882,7 +1903,7 @@ function parse($TEXT, options) {
|
|||||||
var newexp = expr_atom(false), args;
|
var newexp = expr_atom(false), args;
|
||||||
if (is("punc", "(")) {
|
if (is("punc", "(")) {
|
||||||
next();
|
next();
|
||||||
args = expr_list(")");
|
args = expr_list(")", options.ecma >= 8);
|
||||||
} else {
|
} else {
|
||||||
args = [];
|
args = [];
|
||||||
}
|
}
|
||||||
@@ -1989,21 +2010,24 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var expr_atom = function(allow_calls) {
|
var expr_atom = function(allow_calls, allow_arrows) {
|
||||||
if (is("operator", "new")) {
|
if (is("operator", "new")) {
|
||||||
return new_(allow_calls);
|
return new_(allow_calls);
|
||||||
}
|
}
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
|
var async = is("name", "async") && as_atom_node();
|
||||||
if (is("punc")) {
|
if (is("punc")) {
|
||||||
switch (start.value) {
|
switch (S.token.value) {
|
||||||
case "(":
|
case "(":
|
||||||
next();
|
if (async && !allow_calls) break;
|
||||||
var exprs = params_or_seq_();
|
var exprs = params_or_seq_(allow_arrows, !async);
|
||||||
expect(")");
|
if (allow_arrows && is("arrow", "=>")) {
|
||||||
if (is("arrow", "=>")) {
|
return arrow_function(start, exprs.map(to_fun_args), !!async);
|
||||||
return arrow_function(start, exprs.map(to_fun_args));
|
|
||||||
}
|
}
|
||||||
var ex = exprs.length == 1 ? exprs[0] : new AST_Sequence({
|
var ex = async ? new AST_Call({
|
||||||
|
expression: async,
|
||||||
|
args: exprs
|
||||||
|
}) : exprs.length == 1 ? exprs[0] : new AST_Sequence({
|
||||||
expressions: exprs
|
expressions: exprs
|
||||||
});
|
});
|
||||||
ex.start = start;
|
ex.start = start;
|
||||||
@@ -2014,23 +2038,25 @@ function parse($TEXT, options) {
|
|||||||
case "{":
|
case "{":
|
||||||
return subscripts(object_or_destructuring_(), allow_calls);
|
return subscripts(object_or_destructuring_(), allow_calls);
|
||||||
}
|
}
|
||||||
unexpected();
|
if (!async) unexpected();
|
||||||
}
|
}
|
||||||
if (is("name", "async") && is_token(peek(), "keyword", "function")) {
|
if (allow_arrows && is("name") && is_token(peek(), "arrow")) {
|
||||||
|
var param = new AST_SymbolFunarg({
|
||||||
|
name: S.token.value,
|
||||||
|
start: start,
|
||||||
|
end: start,
|
||||||
|
});
|
||||||
next();
|
next();
|
||||||
next();
|
return arrow_function(start, [param], !!async);
|
||||||
var func = function_(AST_Function, false, true);
|
|
||||||
func.start = start;
|
|
||||||
func.end = prev();
|
|
||||||
return subscripts(func, allow_calls);
|
|
||||||
}
|
}
|
||||||
if (is("keyword", "function")) {
|
if (is("keyword", "function")) {
|
||||||
next();
|
next();
|
||||||
var func = function_(AST_Function);
|
var func = function_(AST_Function, false, !!async);
|
||||||
func.start = start;
|
func.start = start;
|
||||||
func.end = prev();
|
func.end = prev();
|
||||||
return subscripts(func, allow_calls);
|
return subscripts(func, allow_calls);
|
||||||
}
|
}
|
||||||
|
if (async) return subscripts(async, allow_calls);
|
||||||
if (is("keyword", "class")) {
|
if (is("keyword", "class")) {
|
||||||
next();
|
next();
|
||||||
var cls = class_(AST_ClassExpression);
|
var cls = class_(AST_ClassExpression);
|
||||||
@@ -2327,6 +2353,14 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function map_name(is_import) {
|
function map_name(is_import) {
|
||||||
|
function make_symbol(type) {
|
||||||
|
return new type({
|
||||||
|
name: as_property_name(),
|
||||||
|
start: prev(),
|
||||||
|
end: prev()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
|
var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
|
||||||
var type = is_import ? AST_SymbolImport : AST_SymbolExport;
|
var type = is_import ? AST_SymbolImport : AST_SymbolExport;
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
@@ -2334,16 +2368,16 @@ function parse($TEXT, options) {
|
|||||||
var name;
|
var name;
|
||||||
|
|
||||||
if (is_import) {
|
if (is_import) {
|
||||||
foreign_name = as_symbol(foreign_type);
|
foreign_name = make_symbol(foreign_type);
|
||||||
} else {
|
} else {
|
||||||
name = as_symbol(type);
|
name = make_symbol(type);
|
||||||
}
|
}
|
||||||
if (is("name", "as")) {
|
if (is("name", "as")) {
|
||||||
next(); // The "as" word
|
next(); // The "as" word
|
||||||
if (is_import) {
|
if (is_import) {
|
||||||
name = as_symbol(type);
|
name = make_symbol(type);
|
||||||
} else {
|
} else {
|
||||||
foreign_name = as_symbol(foreign_type);
|
foreign_name = make_symbol(foreign_type);
|
||||||
}
|
}
|
||||||
} else if (is_import) {
|
} else if (is_import) {
|
||||||
name = new type(foreign_name);
|
name = new type(foreign_name);
|
||||||
@@ -2592,11 +2626,9 @@ function parse($TEXT, options) {
|
|||||||
return expr;
|
return expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
var call_args = embed_tokens(function call_args() {
|
var call_args = embed_tokens(function _call_args() {
|
||||||
var first = true;
|
|
||||||
var args = [];
|
var args = [];
|
||||||
while (!is("punc", ")")) {
|
while (!is("punc", ")")) {
|
||||||
if (first) first = false; else expect(",");
|
|
||||||
if (is("expand", "...")) {
|
if (is("expand", "...")) {
|
||||||
next();
|
next();
|
||||||
args.push(new AST_Expansion({
|
args.push(new AST_Expansion({
|
||||||
@@ -2606,12 +2638,16 @@ function parse($TEXT, options) {
|
|||||||
} else {
|
} else {
|
||||||
args.push(expression(false));
|
args.push(expression(false));
|
||||||
}
|
}
|
||||||
|
if (!is("punc", ")")) {
|
||||||
|
expect(",");
|
||||||
|
if (is("punc", ")") && options.ecma < 8) unexpected();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
return args;
|
return args;
|
||||||
});
|
});
|
||||||
|
|
||||||
var maybe_unary = function(allow_calls) {
|
var maybe_unary = function(allow_calls, allow_arrows) {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
if (start.type == "name" && start.value == "await") {
|
if (start.type == "name" && start.value == "await") {
|
||||||
if (is_in_async()) {
|
if (is_in_async()) {
|
||||||
@@ -2629,8 +2665,9 @@ function parse($TEXT, options) {
|
|||||||
ex.end = prev();
|
ex.end = prev();
|
||||||
return ex;
|
return ex;
|
||||||
}
|
}
|
||||||
var val = expr_atom(allow_calls);
|
var val = expr_atom(allow_calls, allow_arrows);
|
||||||
while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) {
|
while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) {
|
||||||
|
if (val instanceof AST_Arrow) unexpected();
|
||||||
val = make_unary(AST_UnaryPostfix, S.token, val);
|
val = make_unary(AST_UnaryPostfix, S.token, val);
|
||||||
val.start = start;
|
val.start = start;
|
||||||
val.end = S.token;
|
val.end = S.token;
|
||||||
@@ -2678,7 +2715,7 @@ function parse($TEXT, options) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function expr_ops(no_in) {
|
function expr_ops(no_in) {
|
||||||
return expr_op(maybe_unary(true), 0, no_in);
|
return expr_op(maybe_unary(true, true), 0, no_in);
|
||||||
};
|
};
|
||||||
|
|
||||||
var maybe_conditional = function(no_in) {
|
var maybe_conditional = function(no_in) {
|
||||||
@@ -2759,22 +2796,6 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start.type == "punc" && start.value == "(" && peek().value == ")") {
|
|
||||||
next();
|
|
||||||
next();
|
|
||||||
return arrow_function(start, []);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is("name") && is_token(peek(), "arrow")) {
|
|
||||||
var param = new AST_SymbolFunarg({
|
|
||||||
name: start.value,
|
|
||||||
start: start,
|
|
||||||
end: start,
|
|
||||||
});
|
|
||||||
next();
|
|
||||||
return arrow_function(start, [param]);
|
|
||||||
}
|
|
||||||
|
|
||||||
var left = maybe_conditional(no_in);
|
var left = maybe_conditional(no_in);
|
||||||
var val = S.token.value;
|
var val = S.token.value;
|
||||||
|
|
||||||
|
|||||||
139
lib/scope.js
139
lib/scope.js
@@ -132,7 +132,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
scope = save_scope;
|
scope = save_scope;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Destructuring && node.is_array === false) {
|
if (node instanceof AST_Destructuring) {
|
||||||
in_destructuring = node; // These don't nest
|
in_destructuring = node; // These don't nest
|
||||||
descend();
|
descend();
|
||||||
in_destructuring = null;
|
in_destructuring = null;
|
||||||
@@ -263,8 +263,9 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
s.uses_eval = true;
|
s.uses_eval = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var sym = node.scope.find_variable(name);
|
var sym;
|
||||||
if (!sym) {
|
if (tw.parent() instanceof AST_NameMapping && tw.parent(1).module_name
|
||||||
|
|| !(sym = node.scope.find_variable(name))) {
|
||||||
sym = self.def_global(node);
|
sym = self.def_global(node);
|
||||||
} else if (sym.scope instanceof AST_Lambda && name == "arguments") {
|
} else if (sym.scope instanceof AST_Lambda && name == "arguments") {
|
||||||
sym.scope.uses_arguments = true;
|
sym.scope.uses_arguments = true;
|
||||||
@@ -449,7 +450,7 @@ AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
|||||||
|
|
||||||
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
||||||
var def = this.definition();
|
var def = this.definition();
|
||||||
return def && def.unmangleable(options);
|
return !def || def.unmangleable(options);
|
||||||
});
|
});
|
||||||
|
|
||||||
// labels are always mangleable
|
// labels are always mangleable
|
||||||
@@ -554,113 +555,69 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
||||||
options = this._default_mangler_options(options);
|
options = this._default_mangler_options(options);
|
||||||
var tw = new TreeWalker(function(node){
|
try {
|
||||||
if (node instanceof AST_Constant)
|
AST_Node.prototype.print = function(stream, force_parens) {
|
||||||
base54.consider(node.print_to_string());
|
this._print(stream, force_parens);
|
||||||
else if (node instanceof AST_Return)
|
if (this instanceof AST_Symbol && !this.unmangleable(options)) {
|
||||||
base54.consider("return");
|
base54.consider(this.name, -1);
|
||||||
else if (node instanceof AST_Throw)
|
} else if (options.properties) {
|
||||||
base54.consider("throw");
|
if (this instanceof AST_Dot) {
|
||||||
else if (node instanceof AST_Continue)
|
base54.consider(this.property, -1);
|
||||||
base54.consider("continue");
|
} else if (this instanceof AST_Sub) {
|
||||||
else if (node instanceof AST_Break)
|
skip_string(this.property);
|
||||||
base54.consider("break");
|
}
|
||||||
else if (node instanceof AST_Debugger)
|
}
|
||||||
base54.consider("debugger");
|
};
|
||||||
else if (node instanceof AST_Directive)
|
base54.consider(this.print_to_string(), 1);
|
||||||
base54.consider(node.value);
|
} finally {
|
||||||
else if (node instanceof AST_While)
|
AST_Node.prototype.print = AST_Node.prototype._print;
|
||||||
base54.consider("while");
|
}
|
||||||
else if (node instanceof AST_Do)
|
|
||||||
base54.consider("do while");
|
|
||||||
else if (node instanceof AST_If) {
|
|
||||||
base54.consider("if");
|
|
||||||
if (node.alternative) base54.consider("else");
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_Var)
|
|
||||||
base54.consider("var");
|
|
||||||
else if (node instanceof AST_Const)
|
|
||||||
base54.consider("const");
|
|
||||||
else if (node instanceof AST_Lambda)
|
|
||||||
base54.consider("function");
|
|
||||||
else if (node instanceof AST_For)
|
|
||||||
base54.consider("for");
|
|
||||||
else if (node instanceof AST_ForIn)
|
|
||||||
base54.consider("for in");
|
|
||||||
else if (node instanceof AST_Switch)
|
|
||||||
base54.consider("switch");
|
|
||||||
else if (node instanceof AST_Case)
|
|
||||||
base54.consider("case");
|
|
||||||
else if (node instanceof AST_Default)
|
|
||||||
base54.consider("default");
|
|
||||||
else if (node instanceof AST_With)
|
|
||||||
base54.consider("with");
|
|
||||||
else if (node instanceof AST_ObjectSetter)
|
|
||||||
base54.consider("set" + (typeof node.key === "string" ? node.key : ""));
|
|
||||||
else if (node instanceof AST_ObjectGetter)
|
|
||||||
base54.consider("get" + (typeof node.key === "string" ? node.key : ""));
|
|
||||||
else if (node instanceof AST_ObjectKeyVal && typeof node.key === "string")
|
|
||||||
base54.consider(node.key);
|
|
||||||
else if (node instanceof AST_ConciseMethod && typeof node.key === "string")
|
|
||||||
base54.consider(node.key);
|
|
||||||
else if (node instanceof AST_New)
|
|
||||||
base54.consider("new");
|
|
||||||
else if (node instanceof AST_This)
|
|
||||||
base54.consider("this");
|
|
||||||
else if (node instanceof AST_Super)
|
|
||||||
base54.consider("super");
|
|
||||||
else if (node instanceof AST_Try)
|
|
||||||
base54.consider("try");
|
|
||||||
else if (node instanceof AST_Catch)
|
|
||||||
base54.consider("catch");
|
|
||||||
else if (node instanceof AST_Finally)
|
|
||||||
base54.consider("finally");
|
|
||||||
else if (node instanceof AST_Yield)
|
|
||||||
base54.consider("yield");
|
|
||||||
else if (node instanceof AST_Await)
|
|
||||||
base54.consider("await");
|
|
||||||
else if (node instanceof AST_Symbol && node.unmangleable(options))
|
|
||||||
base54.consider(node.name);
|
|
||||||
else if (node instanceof AST_Unary || node instanceof AST_Binary)
|
|
||||||
base54.consider(node.operator);
|
|
||||||
else if (node instanceof AST_Dot)
|
|
||||||
base54.consider(node.property);
|
|
||||||
});
|
|
||||||
this.walk(tw);
|
|
||||||
base54.sort();
|
base54.sort();
|
||||||
|
|
||||||
|
function skip_string(node) {
|
||||||
|
if (node instanceof AST_String) {
|
||||||
|
base54.consider(node.value, -1);
|
||||||
|
} else if (node instanceof AST_Conditional) {
|
||||||
|
skip_string(node.consequent);
|
||||||
|
skip_string(node.alternative);
|
||||||
|
} else if (node instanceof AST_Sequence) {
|
||||||
|
skip_string(node.expressions[node.expressions.length - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var base54 = (function() {
|
var base54 = (function() {
|
||||||
var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789";
|
var leading = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_".split("");
|
||||||
|
var digits = "0123456789".split("");
|
||||||
var chars, frequency;
|
var chars, frequency;
|
||||||
function reset() {
|
function reset() {
|
||||||
frequency = Object.create(null);
|
frequency = Object.create(null);
|
||||||
chars = string.split("").map(function(ch){ return ch.charCodeAt(0) });
|
leading.forEach(function(ch) {
|
||||||
chars.forEach(function(ch){ frequency[ch] = 0 });
|
frequency[ch] = 0;
|
||||||
|
});
|
||||||
|
digits.forEach(function(ch) {
|
||||||
|
frequency[ch] = 0;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
base54.consider = function(str){
|
base54.consider = function(str, delta) {
|
||||||
for (var i = str.length; --i >= 0;) {
|
for (var i = str.length; --i >= 0;) {
|
||||||
var code = str.charCodeAt(i);
|
frequency[str[i]] += delta;
|
||||||
if (code in frequency) ++frequency[code];
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
function compare(a, b) {
|
||||||
|
return frequency[b] - frequency[a];
|
||||||
|
}
|
||||||
base54.sort = function() {
|
base54.sort = function() {
|
||||||
chars = mergeSort(chars, function(a, b){
|
chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
|
||||||
if (is_digit(a) && !is_digit(b)) return 1;
|
|
||||||
if (is_digit(b) && !is_digit(a)) return -1;
|
|
||||||
return frequency[b] - frequency[a];
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
base54.reset = reset;
|
base54.reset = reset;
|
||||||
reset();
|
reset();
|
||||||
base54.get = function(){ return chars };
|
|
||||||
base54.freq = function(){ return frequency };
|
|
||||||
function base54(num) {
|
function base54(num) {
|
||||||
var ret = "", base = 54;
|
var ret = "", base = 54;
|
||||||
num++;
|
num++;
|
||||||
do {
|
do {
|
||||||
num--;
|
num--;
|
||||||
ret += String.fromCharCode(chars[num % base]);
|
ret += chars[num % base];
|
||||||
num = Math.floor(num / base);
|
num = Math.floor(num / base);
|
||||||
base = 64;
|
base = 64;
|
||||||
} while (num > 0);
|
} while (num > 0);
|
||||||
|
|||||||
17
package.json
17
package.json
@@ -4,7 +4,7 @@
|
|||||||
"homepage": "https://github.com/mishoo/UglifyJS2/tree/harmony",
|
"homepage": "https://github.com/mishoo/UglifyJS2/tree/harmony",
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "3.0.19",
|
"version": "3.0.21",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
@@ -40,5 +40,18 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node test/run-tests.js"
|
"test": "node test/run-tests.js"
|
||||||
},
|
},
|
||||||
"keywords": ["uglify", "uglify-js", "uglify-es", "minify", "minifier", "es5", "es6", "es2015"]
|
"keywords": [
|
||||||
|
"uglify",
|
||||||
|
"uglify-js",
|
||||||
|
"uglify-es",
|
||||||
|
"minify",
|
||||||
|
"minifier",
|
||||||
|
"es5",
|
||||||
|
"es6",
|
||||||
|
"es2015",
|
||||||
|
"es2016",
|
||||||
|
"es2017",
|
||||||
|
"async",
|
||||||
|
"await"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -202,3 +202,339 @@ arrow_unused_toplevel: {
|
|||||||
expect_stdout: [ "0", "1", "2", "9" ]
|
expect_stdout: [ "0", "1", "2", "9" ]
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
no_leading_parentheses: {
|
||||||
|
input: {
|
||||||
|
(x,y) => x(y);
|
||||||
|
async (x,y) => await x(y);
|
||||||
|
}
|
||||||
|
expect_exact: "(x,y)=>x(y);async(x,y)=>await x(y);"
|
||||||
|
}
|
||||||
|
|
||||||
|
async_identifiers: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
ecma: 6,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var async = function(x){ console.log("async", x); };
|
||||||
|
var await = function(x){ console.log("await", x); };
|
||||||
|
async(1);
|
||||||
|
await(2);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var async = x => { console.log("async", x); };
|
||||||
|
var await = x => { console.log("await", x); };
|
||||||
|
async(1);
|
||||||
|
await(2);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"async 1",
|
||||||
|
"await 2",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
async_function_expression: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var named = async function foo() {
|
||||||
|
await bar(1 + 0) + (2 + 0);
|
||||||
|
}
|
||||||
|
var anon = async function() {
|
||||||
|
await (1 + 0) + bar(2 + 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var named = async function foo() {
|
||||||
|
await bar(1);
|
||||||
|
};
|
||||||
|
var anon = async () => {
|
||||||
|
await 1, bar(2);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_27: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
ecma: 6,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(jQuery) {
|
||||||
|
var $;
|
||||||
|
$ = jQuery;
|
||||||
|
$("body").addClass("foo");
|
||||||
|
})(jQuery);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(jQuery => {
|
||||||
|
jQuery("body").addClass("foo");
|
||||||
|
})(jQuery);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2105_1: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
ecma: 6,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function(factory) {
|
||||||
|
factory();
|
||||||
|
}( function() {
|
||||||
|
return function(fn) {
|
||||||
|
fn()().prop();
|
||||||
|
}( function() {
|
||||||
|
function bar() {
|
||||||
|
var quux = function() {
|
||||||
|
console.log("PASS");
|
||||||
|
}, foo = function() {
|
||||||
|
console.log;
|
||||||
|
quux();
|
||||||
|
};
|
||||||
|
return { prop: foo };
|
||||||
|
}
|
||||||
|
return bar;
|
||||||
|
} );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!void (() => {
|
||||||
|
var quux = () => {
|
||||||
|
console.log("PASS");
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
prop: () => {
|
||||||
|
console.log;
|
||||||
|
quux();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})().prop();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2105_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
((factory) => {
|
||||||
|
factory();
|
||||||
|
})( () => {
|
||||||
|
return ((fn) => {
|
||||||
|
fn()().prop();
|
||||||
|
})( () => {
|
||||||
|
let bar = () => {
|
||||||
|
var quux = () => {
|
||||||
|
console.log("PASS");
|
||||||
|
}, foo = () => {
|
||||||
|
console.log;
|
||||||
|
quux();
|
||||||
|
};
|
||||||
|
return { prop: foo };
|
||||||
|
};
|
||||||
|
return bar;
|
||||||
|
} );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!void (() => {
|
||||||
|
var quux = () => {
|
||||||
|
console.log("PASS");
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
prop: () => {
|
||||||
|
console.log;
|
||||||
|
quux();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})().prop();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2136_2: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
ecma: 6,
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
!function(a, ...b) {
|
||||||
|
f(b[0]);
|
||||||
|
}(1, 2, 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
f([2,3][0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2136_3: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
!function(a, ...b) {
|
||||||
|
f(b[0]);
|
||||||
|
}(1, 2, 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(2);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
call_args: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const a = 1;
|
||||||
|
console.log(a);
|
||||||
|
+function(a) {
|
||||||
|
return a;
|
||||||
|
}(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const a = 1;
|
||||||
|
console.log(1);
|
||||||
|
+(1, 1);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
call_args_drop_param: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const a = 1;
|
||||||
|
console.log(a);
|
||||||
|
+function(a) {
|
||||||
|
return a;
|
||||||
|
}(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const a = 1;
|
||||||
|
console.log(1);
|
||||||
|
+(b, 1);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_485_crashing_1530: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
if (true) return;
|
||||||
|
var b = 42;
|
||||||
|
})(this);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
this, void 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2084: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
!function() {
|
||||||
|
!function(c) {
|
||||||
|
c = 1 + c;
|
||||||
|
var c = 0;
|
||||||
|
function f14(a_1) {
|
||||||
|
if (c = 1 + c, 0 !== 23..toString())
|
||||||
|
c = 1 + c, a_1 && (a_1[0] = 0);
|
||||||
|
}
|
||||||
|
f14();
|
||||||
|
}(-1);
|
||||||
|
}();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
!((c) => {
|
||||||
|
c = 1 + c,
|
||||||
|
c = 1 + (c = 0),
|
||||||
|
0 !== 23..toString() && (c = 1 + c);
|
||||||
|
})(-1),
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -167,14 +167,14 @@ async_inline: {
|
|||||||
|
|
||||||
async_identifiers: {
|
async_identifiers: {
|
||||||
input: {
|
input: {
|
||||||
let async = function(x){ console.log("async", x); };
|
var async = function(x){ console.log("async", x); };
|
||||||
let await = function(x){ console.log("await", x); };
|
var await = function(x){ console.log("await", x); };
|
||||||
async(1);
|
async(1);
|
||||||
await(2);
|
await(2);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
let async = function(x){ console.log("async", x); };
|
var async = function(x){ console.log("async", x); };
|
||||||
let await = function(x){ console.log("await", x); };
|
var await = function(x){ console.log("await", x); };
|
||||||
async(1);
|
async(1);
|
||||||
await(2);
|
await(2);
|
||||||
}
|
}
|
||||||
@@ -182,7 +182,6 @@ async_identifiers: {
|
|||||||
"async 1",
|
"async 1",
|
||||||
"await 2",
|
"await 2",
|
||||||
]
|
]
|
||||||
node_version: ">=8"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async_shorthand_property: {
|
async_shorthand_property: {
|
||||||
@@ -230,16 +229,26 @@ async_shorthand_property: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: add test when supported by parser
|
|
||||||
async_arrow: {
|
async_arrow: {
|
||||||
input: {
|
input: {
|
||||||
let a1 = async x => await foo(x);
|
let a1 = async x => await foo(x);
|
||||||
let a2 = async () => await bar();
|
let a2 = async () => await bar();
|
||||||
let a3 = async (x) => await baz(x);
|
let a3 = async (x) => await baz(x);
|
||||||
let a4 = async (x, y) => { await far(x, y); }
|
let a4 = async (x, y) => { await far(x, y); }
|
||||||
let a5 = async ({x = [1], y: z = 2}) => { await wow(x, y); }
|
let a5 = async ({x = [1], y: z = 2}) => { await wow(x, z); }
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
let a1 = async x => await foo(x);
|
||||||
|
let a2 = async () => await bar();
|
||||||
|
let a3 = async (x) => await baz(x);
|
||||||
|
let a4 = async (x, y) => { await far(x, y); }
|
||||||
|
let a5 = async ({x = [1], y: z = 2}) => { await wow(x, z); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
async_arrow_wait: {
|
||||||
|
input: {
|
||||||
|
var a = async (x, y) => await x(y);
|
||||||
|
}
|
||||||
|
expect_exact: "var a=async(x,y)=>await x(y);"
|
||||||
|
}
|
||||||
|
|||||||
@@ -104,34 +104,36 @@ regression_block_scope_resolves: {
|
|||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
(function () {
|
(function () {
|
||||||
if(1) {
|
if (1) {
|
||||||
let x;
|
let x;
|
||||||
const y;
|
const y = 1;
|
||||||
class Zee {};
|
class Zee {};
|
||||||
}
|
}
|
||||||
if(1) {
|
if (1) {
|
||||||
let ex;
|
let ex;
|
||||||
const why;
|
const why = 2;
|
||||||
class Zi {};
|
class Zi {};
|
||||||
}
|
}
|
||||||
console.log(x, y, Zee, ex, why, Zi);
|
console.log(typeof x, typeof y, typeof Zee, typeof ex, typeof why, typeof Zi);
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(function () {
|
(function () {
|
||||||
if (1) {
|
if (1) {
|
||||||
let o;
|
let e;
|
||||||
const n;
|
const o = 1;
|
||||||
class c {};
|
class t {};
|
||||||
}
|
}
|
||||||
if (1) {
|
if (1) {
|
||||||
let o;
|
let e;
|
||||||
const n;
|
const o = 2;
|
||||||
class c {};
|
class t {};
|
||||||
}
|
}
|
||||||
console.log(x, y, Zee, ex, why, Zi);
|
console.log(typeof x, typeof y, typeof Zee, typeof ex, typeof why, typeof Zi);
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
|
expect_stdout: "undefined undefined undefined undefined undefined undefined"
|
||||||
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_block_scope_mangler: {
|
switch_block_scope_mangler: {
|
||||||
@@ -153,25 +155,37 @@ switch_block_scope_mangler: {
|
|||||||
console.log(cat);
|
console.log(cat);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
fn(1);
|
||||||
|
fn(2);
|
||||||
|
fn(3);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var fn = function(o) {
|
var fn = function(e) {
|
||||||
switch (o) {
|
switch (e) {
|
||||||
case 1:
|
case 1:
|
||||||
let e = o + 1
|
let l = e + 1
|
||||||
let c = o + 4;
|
let o = e + 4;
|
||||||
console.log(e, c);
|
console.log(l, o);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
let l = o + 2;
|
let n = e + 2;
|
||||||
console.log(l);
|
console.log(n);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
let a = o + 3;
|
let c = e + 3;
|
||||||
console.log(a);
|
console.log(c);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
fn(1);
|
||||||
|
fn(2);
|
||||||
|
fn(3);
|
||||||
}
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"2 5",
|
||||||
|
"4",
|
||||||
|
"6",
|
||||||
|
]
|
||||||
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -425,8 +425,8 @@ mangle_destructuring_decl: {
|
|||||||
expect: {
|
expect: {
|
||||||
function test(t) {
|
function test(t) {
|
||||||
let e = t.a || { e: 7, n: 8 };
|
let e = t.a || { e: 7, n: 8 };
|
||||||
let {t: n, e: o, n: s, s: a = 9, o: c, r: l} = e;
|
let {t: n, e: o, n: s, s: l = 9, o: a, r: c} = e;
|
||||||
console.log(n, o, s, a, c, l);
|
console.log(n, o, s, l, a, c);
|
||||||
}
|
}
|
||||||
test({ a: { t: 1, e: 2, n: 3, s: 4, o: 5, r: 6 } });
|
test({ a: { t: 1, e: 2, n: 3, s: 4, o: 5, r: 6 } });
|
||||||
test({});
|
test({});
|
||||||
@@ -462,15 +462,15 @@ mangle_destructuring_assign_toplevel_true: {
|
|||||||
test({});
|
test({});
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function n(n) {
|
function e(e) {
|
||||||
let t, a, c;
|
let l, s, a;
|
||||||
let l = n.a || { e: 7, n: 8 };
|
let c = e.a || { e: 7, n: 8 };
|
||||||
({t: o, e, n: s, s: t = 9, o: a, r: c} = l);
|
({t: n, e: o, n: t, s: l = 9, o: s, r: a} = c);
|
||||||
console.log(o, e, s, t, a, c);
|
console.log(n, o, t, l, s, a);
|
||||||
}
|
}
|
||||||
let o, e, s;
|
let n, o, t;
|
||||||
n({ a: { t: 1, e: 2, n: 3, s: 4, o: 5, r: 6 } });
|
e({ a: { t: 1, e: 2, n: 3, s: 4, o: 5, r: 6 } });
|
||||||
n({});
|
e({});
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"1 2 3 4 5 6",
|
"1 2 3 4 5 6",
|
||||||
@@ -504,10 +504,10 @@ mangle_destructuring_assign_toplevel_false: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function test(o) {
|
function test(o) {
|
||||||
let s, a, c;
|
let s, l, a;
|
||||||
let l = o.a || { e: 7, n: 8 };
|
let c = o.a || { e: 7, n: 8 };
|
||||||
({t, e, n, s = 9, o: a, r: c} = l);
|
({t, e, n, s = 9, o: l, r: a} = c);
|
||||||
console.log(t, e, n, s, a, c);
|
console.log(t, e, n, s, l, a);
|
||||||
}
|
}
|
||||||
let t, e, n;
|
let t, e, n;
|
||||||
test({ a: { t: 1, e: 2, n: 3, s: 4, o: 5, r: 6 } });
|
test({ a: { t: 1, e: 2, n: 3, s: 4, o: 5, r: 6 } });
|
||||||
@@ -588,8 +588,8 @@ arrow_func_with_destructuring_args: {
|
|||||||
})({bar: 5 - 0}, [, 6]);
|
})({bar: 5 - 0}, [, 6]);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(({foo: o = 1, bar: n = 2}, [a = 3, b = 4]) => {
|
(({foo: o = 1, bar: a = 2}, [b = 3, l = 4]) => {
|
||||||
console.log(o, n, a, b);
|
console.log(o, a, b, l);
|
||||||
})({bar: 5}, [, 6]);
|
})({bar: 5}, [, 6]);
|
||||||
}
|
}
|
||||||
expect_stdout: "1 5 3 6"
|
expect_stdout: "1 5 3 6"
|
||||||
@@ -639,3 +639,23 @@ issue_2044_ecma_6_beautify: {
|
|||||||
}
|
}
|
||||||
expect_exact: "({x: a = 1, y = 2 + b, z = 3 - c} = obj);"
|
expect_exact: "({x: a = 1, y = 2 + b, z = 3 - c} = obj);"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2140: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
var t = {};
|
||||||
|
console.log(([t.a] = [42])[0]);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
var t = {};
|
||||||
|
console.log(([t.a] = [42])[0]);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1409,3 +1409,20 @@ issue_2136_3: {
|
|||||||
expect_stdout: "2"
|
expect_stdout: "2"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2163: {
|
||||||
|
options = {
|
||||||
|
pure_funcs: [ "pure" ],
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c;
|
||||||
|
/*@__PURE__*/f(...a);
|
||||||
|
pure(b, ...c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c;
|
||||||
|
a;
|
||||||
|
b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ issue_2038_2: {
|
|||||||
export { LET, CONST, VAR };
|
export { LET, CONST, VAR };
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
let a = 1;
|
let t = 1;
|
||||||
const c = 2;
|
const e = 2;
|
||||||
var n = 3;
|
var o = 3;
|
||||||
export { a as LET, c as CONST, n as VAR };
|
export { t as LET, e as CONST, o as VAR };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,10 +51,10 @@ issue_2126: {
|
|||||||
export { dog };
|
export { dog };
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
import { foo as o, cat as f } from "stuff";
|
import { foo as o, cat as s } from "stuff";
|
||||||
console.log(o, f);
|
console.log(o, s);
|
||||||
export { o as qux };
|
export { o as qux };
|
||||||
export { f as dog };
|
export { s as dog };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,3 +154,75 @@ issue_2134_2: {
|
|||||||
Foo.prototype = {};
|
Foo.prototype = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
redirection: {
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
let foo = 1, bar = 2;
|
||||||
|
export { foo as delete };
|
||||||
|
export { bar as default };
|
||||||
|
export { foo as var } from "module.js";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
let e = 1, o = 2;
|
||||||
|
export { e as delete };
|
||||||
|
export { o as default };
|
||||||
|
export { foo as var } from "module.js";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword_invalid_1: {
|
||||||
|
input: {
|
||||||
|
export { default };
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export { default };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword_invalid_2: {
|
||||||
|
input: {
|
||||||
|
export { default as Alias };
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export { default as Alias };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword_invalid_3: {
|
||||||
|
input: {
|
||||||
|
export { default as default };
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export { default as default };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword_valid_1: {
|
||||||
|
input: {
|
||||||
|
export { default } from "module.js";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export { default } from "module.js";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword_valid_2: {
|
||||||
|
input: {
|
||||||
|
export { default as Alias } from "module.js";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export { default as Alias } from "module.js";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword_valid_3: {
|
||||||
|
input: {
|
||||||
|
export { default as default } from "module.js";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export { default as default } from "module.js";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ issue_203: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var m = {};
|
var m = {};
|
||||||
var fn = Function("a", "b", "b.exports=42");
|
var fn = Function("n,o", "o.exports=42");
|
||||||
fn(null, m, m.exports);
|
fn(null, m, m.exports);
|
||||||
console.log(m.exports);
|
console.log(m.exports);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,3 +174,24 @@ issue_1986: {
|
|||||||
console.log(42);
|
console.log(42);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2167: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
global_defs: {
|
||||||
|
"@isDevMode": "function(){}",
|
||||||
|
},
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (isDevMode()) {
|
||||||
|
greetOverlord();
|
||||||
|
}
|
||||||
|
doWork();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
doWork();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,9 +16,12 @@ typeof_arrow_functions: {
|
|||||||
evaluate: true
|
evaluate: true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var foo = typeof (x) => null;
|
var foo = typeof (x => null);
|
||||||
|
console.log(foo);
|
||||||
}
|
}
|
||||||
expect_exact: "var foo=\"function\";"
|
expect_exact: "var foo=\"function\";console.log(foo);"
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
classes: {
|
classes: {
|
||||||
@@ -60,15 +63,15 @@ class_name_can_be_mangled: {
|
|||||||
function x() {
|
function x() {
|
||||||
class Foo {
|
class Foo {
|
||||||
}
|
}
|
||||||
var class1 = Foo
|
var class1 = Foo;
|
||||||
var class2 = class Bar {}
|
var class2 = class Bar {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function x() {
|
function x() {
|
||||||
class a { }
|
class a { }
|
||||||
var n = a
|
var s = a;
|
||||||
var r = class a {}
|
var c = class a {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -287,12 +290,12 @@ import_statement_mangling: {
|
|||||||
Whatever();
|
Whatever();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
import l from "foo";
|
import o from "foo";
|
||||||
import e, {Food as o} from "lel";
|
import m, {Food as r} from "lel";
|
||||||
import {What as f} from "lel";
|
import {What as f} from "lel";
|
||||||
l();
|
|
||||||
e();
|
|
||||||
o();
|
o();
|
||||||
|
m();
|
||||||
|
r();
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -466,10 +469,10 @@ issue_1898: {
|
|||||||
expect: {
|
expect: {
|
||||||
class Foo {
|
class Foo {
|
||||||
bar() {
|
bar() {
|
||||||
for (const n of [ 6, 5 ])
|
for (const f of [ 6, 5 ])
|
||||||
for (let r of [ 4, 3 ])
|
for (let r of [ 4, 3 ])
|
||||||
for (var o of [ 2, 1 ])
|
for (var o of [ 2, 1 ])
|
||||||
console.log(n, r, o);
|
console.log(f, r, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new Foo().bar();
|
new Foo().bar();
|
||||||
@@ -494,9 +497,9 @@ issue_1753: {
|
|||||||
expect: {
|
expect: {
|
||||||
class SomeClass {
|
class SomeClass {
|
||||||
constructor(r) {
|
constructor(r) {
|
||||||
let a = [];
|
let s = [];
|
||||||
for (let s = 0; s < 6; s++)
|
for (let a = 0; a < 6; a++)
|
||||||
a.push({
|
s.push({
|
||||||
mainDrawNumbers: [],
|
mainDrawNumbers: [],
|
||||||
extraDrawNumbers: []
|
extraDrawNumbers: []
|
||||||
});
|
});
|
||||||
@@ -523,9 +526,9 @@ issue_1753_disable: {
|
|||||||
expect: {
|
expect: {
|
||||||
class SomeClass {
|
class SomeClass {
|
||||||
constructor(r) {
|
constructor(r) {
|
||||||
let a = [];
|
let s = [];
|
||||||
for (let r = 0; r < 6; r++)
|
for (let r = 0; r < 6; r++)
|
||||||
a.push({
|
s.push({
|
||||||
mainDrawNumbers: [],
|
mainDrawNumbers: [],
|
||||||
extraDrawNumbers: []
|
extraDrawNumbers: []
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ issue_1321_no_debug: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.b = 1;
|
x.o = 1;
|
||||||
x["a"] = 2 * x.b;
|
x["a"] = 2 * x.o;
|
||||||
console.log(x.b, x["a"]);
|
console.log(x.o, x["a"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -30,9 +30,9 @@ issue_1321_debug: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.a = 1;
|
x.o = 1;
|
||||||
x["_$foo$_"] = 2 * x.a;
|
x["_$foo$_"] = 2 * x.o;
|
||||||
console.log(x.a, x["_$foo$_"]);
|
console.log(x.o, x["_$foo$_"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -49,9 +49,9 @@ issue_1321_with_quoted: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.a = 1;
|
x.o = 1;
|
||||||
x["b"] = 2 * x.a;
|
x["x"] = 2 * x.o;
|
||||||
console.log(x.a, x["b"]);
|
console.log(x.o, x["x"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ same_variable_in_multiple_for_loop: {
|
|||||||
console.log(o, l);
|
console.log(o, l);
|
||||||
for (let o = 0; o < 2; o++) {
|
for (let o = 0; o < 2; o++) {
|
||||||
console.log(o, l);
|
console.log(o, l);
|
||||||
let c = 2;
|
let e = 2;
|
||||||
console.log(c);
|
console.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,12 +114,12 @@ same_variable_in_multiple_forIn: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var test = [ "a", "b", "c" ];
|
var test = [ "a", "b", "c" ];
|
||||||
for (let o in test) {
|
for (let e in test) {
|
||||||
console.log(o);
|
console.log(e);
|
||||||
let e;
|
let t;
|
||||||
e = [ "e", "f", "g" ];
|
t = [ "e", "f", "g" ];
|
||||||
for (let o in test)
|
for (let e in test)
|
||||||
console.log(o);
|
console.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -160,8 +160,8 @@ different_variable_in_multiple_for_loop: {
|
|||||||
console.log(o, l);
|
console.log(o, l);
|
||||||
for (let o = 0; o < 2; o++) {
|
for (let o = 0; o < 2; o++) {
|
||||||
console.log(o, l);
|
console.log(o, l);
|
||||||
let c = 2;
|
let e = 2;
|
||||||
console.log(c);
|
console.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,12 +241,12 @@ different_variable_in_multiple_forIn: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var test = [ "a", "b", "c" ];
|
var test = [ "a", "b", "c" ];
|
||||||
for (let o in test) {
|
for (let e in test) {
|
||||||
console.log(o);
|
console.log(e);
|
||||||
let e;
|
let t;
|
||||||
e = [ "e", "f", "g" ];
|
t = [ "e", "f", "g" ];
|
||||||
for (let o in test)
|
for (let e in test)
|
||||||
console.log(o);
|
console.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -281,10 +281,10 @@ more_variable_in_multiple_for: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (let o = 9, l = 0; l < 20; l += o) {
|
for (let o = 9, l = 0; l < 20; l += o) {
|
||||||
let c = o++ + l;
|
let e = o++ + l;
|
||||||
console.log(o, c, l);
|
console.log(o, e, l);
|
||||||
for (let l = c, e = c * c, f = 0; f < 10; f++)
|
for (let l = e, t = e * e, c = 0; c < 10; c++)
|
||||||
console.log(o, c, e, l, f);
|
console.log(o, e, t, l, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ numeric_literal: {
|
|||||||
' 42: 2,',
|
' 42: 2,',
|
||||||
' "42": 3,',
|
' "42": 3,',
|
||||||
' 37: 4,',
|
' 37: 4,',
|
||||||
' a: 5,',
|
' o: 5,',
|
||||||
' 1e42: 6,',
|
' 1e42: 6,',
|
||||||
' b: 7,',
|
' b: 7,',
|
||||||
' "1e+42": 8',
|
' "1e+42": 8',
|
||||||
@@ -92,7 +92,7 @@ numeric_literal: {
|
|||||||
'',
|
'',
|
||||||
'console.log(obj[42], obj["42"]);',
|
'console.log(obj[42], obj["42"]);',
|
||||||
'',
|
'',
|
||||||
'console.log(obj[37], obj["a"], obj[37], obj["37"]);',
|
'console.log(obj[37], obj["o"], obj[37], obj["37"]);',
|
||||||
'',
|
'',
|
||||||
'console.log(obj[1e42], obj["b"], obj["1e+42"]);',
|
'console.log(obj[1e42], obj["b"], obj["1e+42"]);',
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ export_mangle_1: {
|
|||||||
return one - two;
|
return one - two;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
expect_exact: "export function foo(n,o){return n-o};"
|
expect_exact: "export function foo(o,n){return o-n};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_mangle_2: {
|
export_mangle_2: {
|
||||||
@@ -171,7 +171,7 @@ export_mangle_2: {
|
|||||||
return one - two;
|
return one - two;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
expect_exact: "export default function foo(n,o){return n-o};"
|
expect_exact: "export default function foo(o,t){return o-t};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_mangle_3: {
|
export_mangle_3: {
|
||||||
@@ -189,7 +189,7 @@ export_mangle_3: {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
expect_exact: "export class C{go(n,r){return n-r+n}};"
|
expect_exact: "export class C{go(r,e){return r-e+r}};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_mangle_4: {
|
export_mangle_4: {
|
||||||
@@ -207,7 +207,7 @@ export_mangle_4: {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
expect_exact: "export default class C{go(n,r){return n-r+n}};"
|
expect_exact: "export default class C{go(e,r){return e-r+e}};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_mangle_5: {
|
export_mangle_5: {
|
||||||
@@ -221,7 +221,7 @@ export_mangle_5: {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
expect_exact: "export default{prop:function(n,r){return n-r}};"
|
expect_exact: "export default{prop:function(r,t){return r-t}};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_mangle_6: {
|
export_mangle_6: {
|
||||||
@@ -232,7 +232,7 @@ export_mangle_6: {
|
|||||||
var baz = 2;
|
var baz = 2;
|
||||||
export let foo = 1, bar = baz;
|
export let foo = 1, bar = baz;
|
||||||
}
|
}
|
||||||
expect_exact: "var a=2;export let foo=1,bar=a;"
|
expect_exact: "var o=2;export let foo=1,bar=o;"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_toplevel_1: {
|
export_toplevel_1: {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ compress_new_function: {
|
|||||||
new Function("aa, bb", 'return aa;');
|
new Function("aa, bb", 'return aa;');
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
Function("a", "b", "return a");
|
Function("n,r", "return n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,8 +27,30 @@ compress_new_function_with_destruct: {
|
|||||||
new Function("[[aa]], [{bb}]", 'return aa;');
|
new Function("[[aa]], [{bb}]", 'return aa;');
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
Function("a", "[b]", "return a");
|
Function("n,[r]", "return n");
|
||||||
Function("a", "{bb:b}", "return a");
|
Function("n,{bb:b}", "return n");
|
||||||
Function("[[a]]", "[{bb:b}]", 'return a');
|
Function("[[n]],[{bb:b}]", "return n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compress_new_function_with_destruct_arrows: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
unsafe: true,
|
||||||
|
unsafe_Func: true,
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new Function("aa, [bb]", 'return aa;');
|
||||||
|
new Function("aa, {bb}", 'return aa;');
|
||||||
|
new Function("[[aa]], [{bb}]", 'return aa;');
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
Function("n,[a]", "return n");
|
||||||
|
Function("b,{bb:n}", "return b");
|
||||||
|
Function("[[b]],[{bb:n}]", "return b");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,41 @@
|
|||||||
dont_reuse_prop: {
|
dont_reuse_prop: {
|
||||||
mangle_props = {
|
mangle_props = {
|
||||||
regex: /asd/
|
regex: /asd/
|
||||||
};
|
}
|
||||||
|
|
||||||
input: {
|
input: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
obj.asd = 256;
|
obj.asd = 256;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
obj.b = 256;
|
obj.b = 256;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
|
expect_stdout: "123"
|
||||||
}
|
}
|
||||||
|
|
||||||
unmangleable_props_should_always_be_reserved: {
|
unmangleable_props_should_always_be_reserved: {
|
||||||
mangle_props = {
|
mangle_props = {
|
||||||
regex: /asd/
|
regex: /asd/
|
||||||
};
|
}
|
||||||
|
|
||||||
input: {
|
input: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.asd = 256;
|
obj.asd = 256;
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.b = 256;
|
obj.b = 256;
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
|
expect_stdout: "123"
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ getter_setter_mangler: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: "function f(n,t){return{get:n,set:t,get g(){},set s(n){},c,a:1,m(){}}}"
|
expect_exact: "function f(t,e){return{get:t,set:e,get g(){},set s(t){},c,a:1,m(){}}}"
|
||||||
}
|
}
|
||||||
|
|
||||||
use_shorthand_opportunity: {
|
use_shorthand_opportunity: {
|
||||||
@@ -297,7 +297,7 @@ concise_methods_and_mangle_props: {
|
|||||||
expect: {
|
expect: {
|
||||||
function x() {
|
function x() {
|
||||||
obj = {
|
obj = {
|
||||||
a() { return 1; }
|
o() { return 1; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
arrow_functions: {
|
arrow_functions: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
(a) => b; // 1 args
|
(a) => b; // 1 args
|
||||||
(a, b) => c; // n args
|
(a, b) => c; // n args
|
||||||
@@ -13,6 +16,9 @@ arrow_functions: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
arrow_return: {
|
arrow_return: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
() => {};
|
() => {};
|
||||||
() => { return; };
|
() => { return; };
|
||||||
|
|||||||
@@ -135,11 +135,11 @@ mangle_properties: {
|
|||||||
a['run']({color: "blue", foo: "baz"});
|
a['run']({color: "blue", foo: "baz"});
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
a["a"] = "bar";
|
a["o"] = "bar";
|
||||||
a.b = "red";
|
a.a = "red";
|
||||||
x = {c: 10};
|
x = {r: 10};
|
||||||
a.d(x.c, a.a);
|
a.b(x.r, a.o);
|
||||||
a['d']({b: "blue", a: "baz"});
|
a['b']({a: "blue", o: "baz"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,16 +178,16 @@ mangle_unquoted_properties: {
|
|||||||
function f1() {
|
function f1() {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a.color = "red";
|
a.color = "red";
|
||||||
a.b = 2;
|
a.o = 2;
|
||||||
x = {"bar": 10, c: 7};
|
x = {"bar": 10, f: 7};
|
||||||
a.c = 9;
|
a.f = 9;
|
||||||
}
|
}
|
||||||
function f2() {
|
function f2() {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
a['color'] = "red";
|
a['color'] = "red";
|
||||||
x = {bar: 10, c: 7};
|
x = {bar: 10, f: 7};
|
||||||
a.c = 9;
|
a.f = 9;
|
||||||
a.b = 3;
|
a.o = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -241,3 +241,147 @@ issue_2110_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "function"
|
expect_stdout: "function"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_immutable_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
1..foo += "";
|
||||||
|
if (1..foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_immutable_2: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "", a.foo ? console.log("FAIL") : console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_immutable_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
1..foo += "";
|
||||||
|
if (1..foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
set_immutable_4: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "", a.foo ? console.log("FAIL") : console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
set_mutable_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function a() {
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("PASS");
|
||||||
|
else console.log("FAIL");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function a() {
|
||||||
|
if (a.foo += "") console.log("PASS");
|
||||||
|
else console.log("FAIL");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_mutable_2: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function a() {
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("PASS");
|
||||||
|
else console.log("FAIL");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function a() {
|
||||||
|
(a.foo += "") ? console.log("PASS") : console.log("FAIL");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -2625,3 +2625,28 @@ issue_2090_2: {
|
|||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for_in_prop: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = {
|
||||||
|
foo: function() {
|
||||||
|
for (this.b in [1, 2]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
a.foo();
|
||||||
|
console.log(a.b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = {
|
||||||
|
foo: function() {
|
||||||
|
for (this.b in [1, 2]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
a.foo();
|
||||||
|
console.log(a.b);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|||||||
4
test/input/invalid/for-in_1.js
Normal file
4
test/input/invalid/for-in_1.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
var a, b = [1, 2];
|
||||||
|
for (1, 2, a in b) {
|
||||||
|
console.log(a, b[a]);
|
||||||
|
}
|
||||||
4
test/input/invalid/for-in_2.js
Normal file
4
test/input/invalid/for-in_2.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
var c = [1, 2];
|
||||||
|
for (var a, b in c) {
|
||||||
|
console.log(a, c[a]);
|
||||||
|
}
|
||||||
1
test/input/invalid/sequence.js
Normal file
1
test/input/invalid/sequence.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
(a, ...b);
|
||||||
@@ -62,23 +62,20 @@ describe("Arrow functions", function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
it("Should not accept arrow functions in the middle or end of an expression", function() {
|
it("Should not accept arrow functions in the middle or end of an expression", function() {
|
||||||
var tests = [
|
[
|
||||||
|
"0 + x => 0",
|
||||||
|
"0 + async x => 0",
|
||||||
"typeof x => 0",
|
"typeof x => 0",
|
||||||
"0 + x => 0"
|
"typeof async x => 0",
|
||||||
];
|
"typeof (x) => null",
|
||||||
var test = function(code) {
|
"typeof async (x) => null",
|
||||||
return function() {
|
].forEach(function(code) {
|
||||||
|
assert.throws(function() {
|
||||||
uglify.parse(code);
|
uglify.parse(code);
|
||||||
}
|
}, function(e) {
|
||||||
}
|
return e instanceof uglify.JS_Parse_Error && /^Unexpected /.test(e.message);
|
||||||
var error = function(e) {
|
}, code);
|
||||||
return e instanceof uglify.JS_Parse_Error &&
|
});
|
||||||
e.message === "Unexpected token: arrow (=>)";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
|
||||||
assert.throws(test(tests[i]), error);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should parse a function containing default assignment correctly", function() {
|
it("Should parse a function containing default assignment correctly", function() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var exec = require("child_process").exec;
|
var exec = require("child_process").exec;
|
||||||
var readFileSync = require("fs").readFileSync;
|
var readFileSync = require("fs").readFileSync;
|
||||||
|
var semver = require("semver");
|
||||||
|
|
||||||
function read(path) {
|
function read(path) {
|
||||||
return readFileSync(path, "utf8");
|
return readFileSync(path, "utf8");
|
||||||
@@ -9,9 +10,11 @@ function read(path) {
|
|||||||
describe("bin/uglifyjs", function () {
|
describe("bin/uglifyjs", function () {
|
||||||
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||||
it("should produce a functional build when using --self", function (done) {
|
it("should produce a functional build when using --self", function (done) {
|
||||||
this.timeout(30000);
|
this.timeout(60000);
|
||||||
|
|
||||||
var command = uglifyjscmd + ' --self -cm --wrap WrappedUglifyJS';
|
var command = uglifyjscmd + ' --self -mc ecma=';
|
||||||
|
command += semver.satisfies(process.version, ">=4") ? "6" : "5";
|
||||||
|
command += ',passes=3,keep_fargs=false,unsafe --wrap WrappedUglifyJS';
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -593,6 +596,51 @@ describe("bin/uglifyjs", function () {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("Should throw syntax error (spread in sequence)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/sequence.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/sequence.js:1,4",
|
||||||
|
"(a, ...b);",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Unexpected token: expand (...)"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (for-in init)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/for-in_1.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/for-in_1.js:2,5",
|
||||||
|
"for (1, 2, a in b) {",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Invalid left-hand side in for..in loop"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (for-in var)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/for-in_2.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/for-in_2.js:2,5",
|
||||||
|
"for (var a, b in c) {",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Only one variable declaration allowed in for..in loop"
|
||||||
|
].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,15 +191,51 @@ describe("Function", function() {
|
|||||||
];
|
];
|
||||||
var test = function(code) {
|
var test = function(code) {
|
||||||
return function() {
|
return function() {
|
||||||
uglify.parse(code);
|
uglify.parse(code, { ecma: 5 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var error = function(e) {
|
var error = function(e) {
|
||||||
return e instanceof uglify.JS_Parse_Error &&
|
return e instanceof uglify.JS_Parse_Error;
|
||||||
e.message === "Invalid function parameter";
|
|
||||||
}
|
}
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.throws(test(tests[i]), error);
|
assert.throws(test(tests[i]), error, tests[i]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
it("Should accept trailing commas only for ES8", function() {
|
||||||
|
[
|
||||||
|
"new Foo(a, );",
|
||||||
|
"async(...[1, 2], );",
|
||||||
|
"console.log(...[1, 2], );",
|
||||||
|
"!function(a, b, ){ console.log(a + b); }(3, 4, );",
|
||||||
|
].forEach(function(code) {
|
||||||
|
uglify.parse(code, { ecma: 8 });
|
||||||
|
assert.throws(function() {
|
||||||
|
uglify.parse(code, { ecma: 6 });
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof uglify.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should not accept invalid trailing commas", function() {
|
||||||
|
var tests = [
|
||||||
|
"f(, );",
|
||||||
|
"(, ) => {};",
|
||||||
|
"(...p, ) => {};",
|
||||||
|
"function f(, ) {}",
|
||||||
|
"function f(...p, ) {}",
|
||||||
|
"function foo(a, b, , ) {}",
|
||||||
|
'console.log("hello", , );',
|
||||||
|
];
|
||||||
|
var test = function(code) {
|
||||||
|
return function() {
|
||||||
|
uglify.parse(code, { ecma: 8 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var error = function(e) {
|
||||||
|
return e instanceof uglify.JS_Parse_Error;
|
||||||
|
}
|
||||||
|
for (var i = 0; i < tests.length; i++) {
|
||||||
|
assert.throws(test(tests[i]), error, tests[i]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it("Should not accept an initializer when parameter is a rest parameter", function() {
|
it("Should not accept an initializer when parameter is a rest parameter", function() {
|
||||||
|
|||||||
@@ -2,29 +2,37 @@ var Uglify = require('../../');
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
|
||||||
describe("let", function() {
|
describe("let", function() {
|
||||||
it("Should not produce `let` as a variable name in mangle", function(done) {
|
it("Should not produce reserved keywords as variable name in mangle", function(done) {
|
||||||
this.timeout(10000);
|
this.timeout(10000);
|
||||||
|
|
||||||
// Produce a lot of variables in a function and run it through mangle.
|
// Produce a lot of variables in a function and run it through mangle.
|
||||||
var s = '"use strict"; function foo() {';
|
var s = '"dddddeeeeelllllooooottttt"; function foo() {';
|
||||||
for (var i = 0; i < 21000; ++i) {
|
for (var i = 0; i < 18000; i++) {
|
||||||
s += "var v" + i + "=0;";
|
s += "var v" + i + "=0;";
|
||||||
}
|
}
|
||||||
s += '}';
|
s += '}';
|
||||||
var result = Uglify.minify(s, {compress: false});
|
var result = Uglify.minify(s, {compress: false});
|
||||||
|
|
||||||
// Verify that select keywords and reserved keywords not produced
|
// Verify that select keywords and reserved keywords not produced
|
||||||
assert.strictEqual(result.code.indexOf("var let="), -1);
|
[
|
||||||
assert.strictEqual(result.code.indexOf("var do="), -1);
|
"do",
|
||||||
assert.strictEqual(result.code.indexOf("var var="), -1);
|
"let",
|
||||||
|
"var",
|
||||||
|
].forEach(function(name) {
|
||||||
|
assert.strictEqual(result.code.indexOf("var " + name + "="), -1);
|
||||||
|
});
|
||||||
|
|
||||||
// Verify that the variable names that appeared immediately before
|
// Verify that the variable names that appeared immediately before
|
||||||
// and after the erroneously generated `let` variable name still exist
|
// and after the erroneously generated variable name still exist
|
||||||
// to show the test generated enough symbols.
|
// to show the test generated enough symbols.
|
||||||
assert(result.code.indexOf("var ket=") >= 0);
|
[
|
||||||
assert(result.code.indexOf("var met=") >= 0);
|
"to", "eo",
|
||||||
|
"eet", "fet",
|
||||||
|
"rar", "oar",
|
||||||
|
].forEach(function(name) {
|
||||||
|
assert.ok(result.code.indexOf("var " + name + "=") >= 0);
|
||||||
|
});
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ describe("minify", function() {
|
|||||||
});
|
});
|
||||||
var err = result.error;
|
var err = result.error;
|
||||||
assert.ok(err instanceof Error);
|
assert.ok(err instanceof Error);
|
||||||
assert.strictEqual(err.stack.split(/\n/)[0], "Error: Can't handle expression: debugger");
|
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token: keyword (debugger)");
|
||||||
});
|
});
|
||||||
it("should skip inherited properties", function() {
|
it("should skip inherited properties", function() {
|
||||||
var foo = Object.create({ skip: this });
|
var foo = Object.create({ skip: this });
|
||||||
|
|||||||
@@ -30,4 +30,13 @@ describe("Template string", function() {
|
|||||||
assert.throws(exec(tests[i]), fail, tests[i]);
|
assert.throws(exec(tests[i]), fail, tests[i]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
it("Should process all line terminators as LF", function() {
|
||||||
|
[
|
||||||
|
"`a\rb`",
|
||||||
|
"`a\nb`",
|
||||||
|
"`a\r\nb`",
|
||||||
|
].forEach(function(code) {
|
||||||
|
assert.strictEqual(uglify.parse(code).print_to_string(), "`a\\nb`;");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ function run_compress_tests() {
|
|||||||
log_start_file(file);
|
log_start_file(file);
|
||||||
function test_case(test) {
|
function test_case(test) {
|
||||||
log_test(test.name);
|
log_test(test.name);
|
||||||
U.base54.reset();
|
|
||||||
var output_options = test.beautify || {};
|
var output_options = test.beautify || {};
|
||||||
var expect;
|
var expect;
|
||||||
if (test.expect) {
|
if (test.expect) {
|
||||||
@@ -101,9 +100,6 @@ function run_compress_tests() {
|
|||||||
quote_style: 3,
|
quote_style: 3,
|
||||||
keep_quoted_props: true
|
keep_quoted_props: true
|
||||||
});
|
});
|
||||||
if (test.mangle_props) {
|
|
||||||
input = U.mangle_properties(input, test.mangle_props);
|
|
||||||
}
|
|
||||||
var options = U.defaults(test.options, {
|
var options = U.defaults(test.options, {
|
||||||
warnings: false
|
warnings: false
|
||||||
});
|
});
|
||||||
@@ -118,10 +114,16 @@ function run_compress_tests() {
|
|||||||
var cmp = new U.Compressor(options, true);
|
var cmp = new U.Compressor(options, true);
|
||||||
var output = cmp.compress(input);
|
var output = cmp.compress(input);
|
||||||
output.figure_out_scope(test.mangle);
|
output.figure_out_scope(test.mangle);
|
||||||
if (test.mangle) {
|
if (test.mangle || test.mangle_props) {
|
||||||
|
U.base54.reset();
|
||||||
output.compute_char_frequency(test.mangle);
|
output.compute_char_frequency(test.mangle);
|
||||||
|
}
|
||||||
|
if (test.mangle) {
|
||||||
output.mangle_names(test.mangle);
|
output.mangle_names(test.mangle);
|
||||||
}
|
}
|
||||||
|
if (test.mangle_props) {
|
||||||
|
output = U.mangle_properties(output, test.mangle_props);
|
||||||
|
}
|
||||||
output = make_code(output, output_options);
|
output = make_code(output, output_options);
|
||||||
if (expect != output) {
|
if (expect != output) {
|
||||||
log("!!! failed\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n---EXPECTED---\n{expected}\n\n", {
|
log("!!! failed\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n---EXPECTED---\n{expected}\n\n", {
|
||||||
|
|||||||
Reference in New Issue
Block a user