Compare commits
12 Commits
harmony-v3
...
harmony-v3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
945db924fc | ||
|
|
087bce508a | ||
|
|
5e6f26445f | ||
|
|
fc7e33453f | ||
|
|
d052394621 | ||
|
|
4d5aeeddfb | ||
|
|
f0a99125ee | ||
|
|
1e4de2e6d3 | ||
|
|
ad139aa34d | ||
|
|
26be15f111 | ||
|
|
179f33f08a | ||
|
|
d260fe9018 |
29
README.md
29
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
|
||||||
-------
|
-------
|
||||||
@@ -434,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.
|
||||||
|
|
||||||
@@ -465,7 +468,6 @@ if (result.error) throw result.error;
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
{
|
{
|
||||||
warnings: false,
|
|
||||||
parse: {
|
parse: {
|
||||||
// parse options
|
// parse options
|
||||||
},
|
},
|
||||||
@@ -485,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,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -540,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
|
||||||
|
|
||||||
@@ -682,6 +689,9 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
functions marked as "pure". A function call is marked as "pure" if a comment
|
functions marked as "pure". A function call is marked as "pure" if a comment
|
||||||
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
|
||||||
|
|
||||||
@@ -691,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).
|
||||||
@@ -754,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
|
||||||
|
|||||||
@@ -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(){
|
||||||
|
|||||||
@@ -94,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"];
|
||||||
@@ -366,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
|
||||||
@@ -564,6 +561,10 @@ merge(Compressor.prototype, {
|
|||||||
return orig.length == 1 && orig[0] instanceof AST_SymbolLambda;
|
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) {
|
||||||
if (lhs instanceof AST_SymbolRef) return 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) {
|
if (lhs instanceof AST_PropAccess) {
|
||||||
@@ -707,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;
|
||||||
}
|
}
|
||||||
@@ -1320,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";
|
||||||
@@ -1593,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;
|
||||||
});
|
});
|
||||||
@@ -1649,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);
|
||||||
|
|
||||||
@@ -1822,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;
|
||||||
@@ -2568,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);
|
||||||
@@ -2672,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);
|
||||||
});
|
});
|
||||||
@@ -3092,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;
|
||||||
@@ -3269,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;
|
||||||
})) {
|
})) {
|
||||||
@@ -3277,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);
|
||||||
@@ -3292,24 +3296,30 @@ merge(Compressor.prototype, {
|
|||||||
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_Function) {
|
if (is_func_expr(node)) {
|
||||||
fun = node;
|
fun = node;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
if (!fun) return self;
|
if (fun.body instanceof AST_Node) {
|
||||||
var args = fun.argnames.map(function(arg, i) {
|
fun.body = [
|
||||||
return make_node(AST_String, self.args[i], {
|
make_node(AST_Return, fun.body, {
|
||||||
value: arg.print_to_string()
|
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) {
|
||||||
@@ -3321,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()) {
|
||||||
@@ -3329,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
|
||||||
@@ -3382,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;
|
||||||
@@ -3408,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);
|
||||||
}
|
}
|
||||||
@@ -4082,7 +4106,7 @@ merge(Compressor.prototype, {
|
|||||||
d.fixed = fixed = make_node(AST_Function, fixed, fixed);
|
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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
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.20",
|
"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"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,3 +280,261 @@ issue_27: {
|
|||||||
})(jQuery);
|
})(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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ issue_203: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var m = {};
|
var m = {};
|
||||||
var fn = Function("n", "o", "o.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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ compress_new_function: {
|
|||||||
new Function("aa, bb", 'return aa;');
|
new Function("aa, bb", 'return aa;');
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
Function("n", "r", "return n");
|
Function("n,r", "return n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,9 +27,9 @@ compress_new_function_with_destruct: {
|
|||||||
new Function("[[aa]], [{bb}]", 'return aa;');
|
new Function("[[aa]], [{bb}]", 'return aa;');
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
Function("n", "[r]", "return n");
|
Function("n,[r]", "return n");
|
||||||
Function("n", "{bb:b}", "return n");
|
Function("n,{bb:b}", "return n");
|
||||||
Function("[[n]]", "[{bb:b}]", "return n");
|
Function("[[n]],[{bb:b}]", "return n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,8 +49,8 @@ compress_new_function_with_destruct_arrows: {
|
|||||||
new Function("[[aa]], [{bb}]", 'return aa;');
|
new Function("[[aa]], [{bb}]", 'return aa;');
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
Function("aa, [bb]", 'return aa;');
|
Function("n,[a]", "return n");
|
||||||
Function("aa, {bb}", 'return aa;');
|
Function("b,{bb:n}", "return b");
|
||||||
Function("[[aa]], [{bb}]", 'return aa;');
|
Function("[[b]],[{bb:n}]", "return b");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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`;");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user