Compare commits
19 Commits
harmony-v3
...
harmony-v3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
067d52b6ba | ||
|
|
e0e009ace2 | ||
|
|
f81ff10a9b | ||
|
|
ae0f117da6 | ||
|
|
a5461e0adc | ||
|
|
16d40915b4 | ||
|
|
2bf8216e50 | ||
|
|
2ed3f8db44 | ||
|
|
4700c14855 | ||
|
|
e7c21e87e3 | ||
|
|
f54ab16843 | ||
|
|
69cb459c16 | ||
|
|
1eae8f2dcc | ||
|
|
c4c2ef44d0 | ||
|
|
a845897758 | ||
|
|
d600c78d7b | ||
|
|
32ea2c5530 | ||
|
|
d3df2f985d | ||
|
|
69861824b5 |
9
.github/ISSUE_TEMPLATE.md
vendored
9
.github/ISSUE_TEMPLATE.md
vendored
@@ -8,7 +8,14 @@
|
|||||||
|
|
||||||
**Uglify version (`uglifyjs -V`)**
|
**Uglify version (`uglifyjs -V`)**
|
||||||
|
|
||||||
**JavaScript input** <!-- ideally as small as possible -->
|
**JavaScript input**
|
||||||
|
|
||||||
|
<!--
|
||||||
|
A complete parsable JS program exhibiting the issue with
|
||||||
|
UglifyJS alone - without third party tools or libraries.
|
||||||
|
Ideally the input should be as small as possible.
|
||||||
|
Post a link to a gist if necessary.
|
||||||
|
-->
|
||||||
|
|
||||||
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
||||||
|
|
||||||
|
|||||||
13
README.md
13
README.md
@@ -646,9 +646,16 @@ 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
|
- `arrows` (default `true`) -- Converts `()=>{return x}` to `()=>x`. Class
|
||||||
to arrow functions if permissible by language semantics.
|
and object literal methods will also be converted to arrow expressions if
|
||||||
Note: `arrows` requires that the `ecma` compress option is set to `6` or greater.
|
the resultant code is shorter: `m(){return x}` becomes `m:()=>x`.
|
||||||
|
This transform requires that the `ecma` compress option is set to `6` or greater.
|
||||||
|
|
||||||
|
- `unsafe_arrows` (default `false`) -- Convert ES5 style anonymous function
|
||||||
|
expressions to arrow functions if the function body does not reference `this`.
|
||||||
|
Note: it is not always safe to perform this conversion if code relies on the
|
||||||
|
the function having a `prototype`, which arrow functions lack.
|
||||||
|
This transform 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`
|
||||||
|
|||||||
@@ -697,7 +697,7 @@ var AST_Export = DEFNODE("Export", "exported_definition exported_value is_defaul
|
|||||||
var AST_VarDef = DEFNODE("VarDef", "name value", {
|
var AST_VarDef = DEFNODE("VarDef", "name value", {
|
||||||
$documentation: "A variable declaration; only appears in a AST_Definitions node",
|
$documentation: "A variable declaration; only appears in a AST_Definitions node",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
name: "[AST_SymbolVar|AST_SymbolConst|AST_Destructuring] name of the variable",
|
name: "[AST_Destructuring|AST_SymbolConst|AST_SymbolLet|AST_SymbolVar] name of the variable",
|
||||||
value: "[AST_Node?] initializer, or null of there's no initializer"
|
value: "[AST_Node?] initializer, or null of there's no initializer"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ function Compressor(options, false_by_default) {
|
|||||||
toplevel : !!(options && options["top_retain"]),
|
toplevel : !!(options && options["top_retain"]),
|
||||||
typeofs : !false_by_default,
|
typeofs : !false_by_default,
|
||||||
unsafe : false,
|
unsafe : false,
|
||||||
|
unsafe_arrows : false,
|
||||||
unsafe_comps : false,
|
unsafe_comps : false,
|
||||||
unsafe_Func : false,
|
unsafe_Func : false,
|
||||||
unsafe_math : false,
|
unsafe_math : false,
|
||||||
@@ -302,6 +303,7 @@ merge(Compressor.prototype, {
|
|||||||
if (reduce_vars) {
|
if (reduce_vars) {
|
||||||
if (node instanceof AST_Toplevel) node.globals.each(reset_def);
|
if (node instanceof AST_Toplevel) node.globals.each(reset_def);
|
||||||
if (node instanceof AST_Scope) node.variables.each(reset_def);
|
if (node instanceof AST_Scope) node.variables.each(reset_def);
|
||||||
|
if (node.block_scope) node.block_scope.variables.each(reset_def);
|
||||||
if (node instanceof AST_SymbolRef) {
|
if (node instanceof AST_SymbolRef) {
|
||||||
var d = node.definition();
|
var d = node.definition();
|
||||||
d.references.push(node);
|
d.references.push(node);
|
||||||
@@ -1426,9 +1428,14 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_Object, function(compressor) {
|
def(AST_Object, function(compressor) {
|
||||||
if (!is_strict(compressor)) return false;
|
if (!is_strict(compressor)) return false;
|
||||||
for (var i = this.properties.length; --i >=0;)
|
for (var i = this.properties.length; --i >=0;)
|
||||||
if (this.properties[i].value instanceof AST_Accessor) return true;
|
if (this.properties[i]._dot_throw(compressor)) return true;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
def(AST_ObjectProperty, return_false);
|
||||||
|
def(AST_ObjectGetter, return_true);
|
||||||
|
def(AST_Expansion, function(compressor) {
|
||||||
|
return this.expression._dot_throw(compressor);
|
||||||
|
});
|
||||||
def(AST_Function, return_false);
|
def(AST_Function, return_false);
|
||||||
def(AST_Arrow, return_false);
|
def(AST_Arrow, return_false);
|
||||||
def(AST_UnaryPostfix, return_false);
|
def(AST_UnaryPostfix, return_false);
|
||||||
@@ -1730,6 +1737,7 @@ merge(Compressor.prototype, {
|
|||||||
var val = {};
|
var val = {};
|
||||||
for (var i = 0, len = this.properties.length; i < len; i++) {
|
for (var i = 0, len = this.properties.length; i < len; i++) {
|
||||||
var prop = this.properties[i];
|
var prop = this.properties[i];
|
||||||
|
if (prop instanceof AST_Expansion) return this;
|
||||||
var key = prop.key;
|
var key = prop.key;
|
||||||
if (key instanceof AST_Symbol) {
|
if (key instanceof AST_Symbol) {
|
||||||
key = key.name;
|
key = key.name;
|
||||||
@@ -4741,7 +4749,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
OPT(AST_Function, function(self, compressor){
|
OPT(AST_Function, function(self, compressor){
|
||||||
tighten_body(self.body, compressor);
|
tighten_body(self.body, compressor);
|
||||||
if (compressor.option("arrows")
|
if (compressor.option("unsafe_arrows")
|
||||||
&& compressor.option("ecma") >= 6
|
&& compressor.option("ecma") >= 6
|
||||||
&& !self.name
|
&& !self.name
|
||||||
&& !self.is_generator
|
&& !self.is_generator
|
||||||
@@ -4823,7 +4831,8 @@ merge(Compressor.prototype, {
|
|||||||
arrow.is_generator = self.is_generator;
|
arrow.is_generator = self.is_generator;
|
||||||
return make_node(AST_ObjectKeyVal, self, {
|
return make_node(AST_ObjectKeyVal, self, {
|
||||||
key: self.key instanceof AST_SymbolMethod ? self.key.name : self.key,
|
key: self.key instanceof AST_SymbolMethod ? self.key.name : self.key,
|
||||||
value: arrow
|
value: arrow,
|
||||||
|
quote: self.quote,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
@@ -4849,6 +4858,7 @@ merge(Compressor.prototype, {
|
|||||||
name: key,
|
name: key,
|
||||||
}),
|
}),
|
||||||
value: make_node(AST_Accessor, value, value),
|
value: make_node(AST_Accessor, value, value),
|
||||||
|
quote: self.quote,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ function minify(files, options) {
|
|||||||
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" ]);
|
||||||
set_shorthand("warnings", options, [ "compress" ]);
|
set_shorthand("warnings", options, [ "compress" ]);
|
||||||
|
var quoted_props;
|
||||||
if (options.mangle) {
|
if (options.mangle) {
|
||||||
options.mangle = defaults(options.mangle, {
|
options.mangle = defaults(options.mangle, {
|
||||||
cache: options.nameCache && (options.nameCache.vars || {}),
|
cache: options.nameCache && (options.nameCache.vars || {}),
|
||||||
@@ -82,11 +83,16 @@ function minify(files, options) {
|
|||||||
safari10: false,
|
safari10: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}, true);
|
}, true);
|
||||||
if (options.nameCache && options.mangle.properties) {
|
if (options.mangle.properties) {
|
||||||
if (typeof options.mangle.properties != "object") {
|
if (typeof options.mangle.properties != "object") {
|
||||||
options.mangle.properties = {};
|
options.mangle.properties = {};
|
||||||
}
|
}
|
||||||
if (!("cache" in options.mangle.properties)) {
|
if (options.mangle.properties.keep_quoted) {
|
||||||
|
quoted_props = options.mangle.properties.reserved;
|
||||||
|
if (!Array.isArray(quoted_props)) quoted_props = [];
|
||||||
|
options.mangle.properties.reserved = quoted_props;
|
||||||
|
}
|
||||||
|
if (options.nameCache && !("cache" in options.mangle.properties)) {
|
||||||
options.mangle.properties.cache = options.nameCache.props || {};
|
options.mangle.properties.cache = options.nameCache.props || {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,6 +135,9 @@ function minify(files, options) {
|
|||||||
}
|
}
|
||||||
toplevel = options.parse.toplevel;
|
toplevel = options.parse.toplevel;
|
||||||
}
|
}
|
||||||
|
if (quoted_props) {
|
||||||
|
reserve_quoted_keys(toplevel, quoted_props);
|
||||||
|
}
|
||||||
if (options.wrap) {
|
if (options.wrap) {
|
||||||
toplevel = toplevel.wrap_commonjs(options.wrap);
|
toplevel = toplevel.wrap_commonjs(options.wrap);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ function OutputStream(options) {
|
|||||||
case "\u2029": return "\\u2029";
|
case "\u2029": return "\\u2029";
|
||||||
case "\ufeff": return "\\ufeff";
|
case "\ufeff": return "\\ufeff";
|
||||||
case "\0":
|
case "\0":
|
||||||
return /[0-7]/.test(get_full_char(str, i+1)) ? "\\x00" : "\\0";
|
return /[0-9]/.test(get_full_char(str, i+1)) ? "\\x00" : "\\0";
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
@@ -689,6 +689,7 @@ function OutputStream(options) {
|
|||||||
* ==> 20 (side effect, set a := 10 and b := 20) */
|
* ==> 20 (side effect, set a := 10 and b := 20) */
|
||||||
|| p instanceof AST_Arrow // x => (x, x)
|
|| p instanceof AST_Arrow // x => (x, x)
|
||||||
|| p instanceof AST_DefaultAssign // x => (x = (0, function(){}))
|
|| p instanceof AST_DefaultAssign // x => (x = (0, function(){}))
|
||||||
|
|| p instanceof AST_Expansion // [...(a, b)]
|
||||||
;
|
;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
55
lib/parse.js
55
lib/parse.js
@@ -1522,7 +1522,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
if (is_expand) {
|
if (is_expand) {
|
||||||
if (!is("punc", "]")) {
|
if (!is("punc", "]")) {
|
||||||
unexpected(); // Must be last element
|
croak("Rest element must be last element");
|
||||||
}
|
}
|
||||||
elements[elements.length - 1] = new AST_Expansion({
|
elements[elements.length - 1] = new AST_Expansion({
|
||||||
start: expand_token,
|
start: expand_token,
|
||||||
@@ -1547,18 +1547,33 @@ function parse($TEXT, options) {
|
|||||||
} else {
|
} else {
|
||||||
expect(",");
|
expect(",");
|
||||||
}
|
}
|
||||||
|
if (is("expand", "...")) {
|
||||||
|
is_expand = true;
|
||||||
|
expand_token = S.token;
|
||||||
|
used_parameters.mark_spread(S.token);
|
||||||
|
next();
|
||||||
|
}
|
||||||
if (is("name") && (is_token(peek(), "punc") || is_token(peek(), "operator")) && [",", "}", "="].indexOf(peek().value) !== -1) {
|
if (is("name") && (is_token(peek(), "punc") || is_token(peek(), "operator")) && [",", "}", "="].indexOf(peek().value) !== -1) {
|
||||||
used_parameters.add_parameter(S.token);
|
used_parameters.add_parameter(S.token);
|
||||||
elements.push(new AST_ObjectKeyVal({
|
var value = new symbol_type({
|
||||||
start: prev(),
|
start: S.token,
|
||||||
key: S.token.value,
|
name: S.token.value,
|
||||||
value: new symbol_type({
|
end: S.token,
|
||||||
start: S.token,
|
});
|
||||||
name: S.token.value,
|
if (is_expand) {
|
||||||
end: S.token
|
elements.push(new AST_Expansion({
|
||||||
}),
|
start: expand_token,
|
||||||
end: prev()
|
expression: value,
|
||||||
}));
|
end: value.end,
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
elements.push(new AST_ObjectKeyVal({
|
||||||
|
start: prev(),
|
||||||
|
key: S.token.value,
|
||||||
|
value: value,
|
||||||
|
end: value.end,
|
||||||
|
}));
|
||||||
|
}
|
||||||
next();
|
next();
|
||||||
} else if (is("punc", "}")) {
|
} else if (is("punc", "}")) {
|
||||||
continue; // Allow trailing hole
|
continue; // Allow trailing hole
|
||||||
@@ -1589,7 +1604,12 @@ function parse($TEXT, options) {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is("operator", "=")) {
|
if (is_expand) {
|
||||||
|
if (!is("punc", "}")) {
|
||||||
|
croak("Rest element must be last element");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (is("operator", "=")) {
|
||||||
used_parameters.mark_default_assignment(S.token);
|
used_parameters.mark_default_assignment(S.token);
|
||||||
next();
|
next();
|
||||||
elements[elements.length - 1].value = new AST_DefaultAssign({
|
elements[elements.length - 1].value = new AST_DefaultAssign({
|
||||||
@@ -2143,7 +2163,18 @@ function parse($TEXT, options) {
|
|||||||
if (!options.strict && is("punc", "}"))
|
if (!options.strict && is("punc", "}"))
|
||||||
// allow trailing comma
|
// allow trailing comma
|
||||||
break;
|
break;
|
||||||
|
|
||||||
start = S.token;
|
start = S.token;
|
||||||
|
if (start.type == "expand") {
|
||||||
|
next();
|
||||||
|
a.push(new AST_Expansion({
|
||||||
|
start: start,
|
||||||
|
expression: expression(false),
|
||||||
|
end: prev(),
|
||||||
|
}));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var name = as_property_name();
|
var name = as_property_name();
|
||||||
var value;
|
var value;
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,36 @@ function find_builtins(reserved) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reserve_quoted_keys(ast, reserved) {
|
||||||
|
function add(name) {
|
||||||
|
push_uniq(reserved, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
ast.walk(new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_ObjectKeyVal && node.quote) {
|
||||||
|
add(node.key);
|
||||||
|
} else if (node instanceof AST_ObjectProperty && node.quote) {
|
||||||
|
add(node.key.name);
|
||||||
|
} else if (node instanceof AST_Sub) {
|
||||||
|
addStrings(node.property, add);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function addStrings(node, add) {
|
||||||
|
node.walk(new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_Sequence) {
|
||||||
|
addStrings(node.expressions[node.expressions.length - 1], add);
|
||||||
|
} else if (node instanceof AST_String) {
|
||||||
|
add(node.value);
|
||||||
|
} else if (node instanceof AST_Conditional) {
|
||||||
|
addStrings(node.consequent, add);
|
||||||
|
addStrings(node.alternative, add);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
function mangle_properties(ast, options) {
|
function mangle_properties(ast, options) {
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
builtins: false,
|
builtins: false,
|
||||||
@@ -109,7 +139,6 @@ function mangle_properties(ast, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var regex = options.regex;
|
var regex = options.regex;
|
||||||
var keep_quoted = options.keep_quoted;
|
|
||||||
|
|
||||||
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
|
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
|
||||||
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
|
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
|
||||||
@@ -122,12 +151,11 @@ function mangle_properties(ast, options) {
|
|||||||
|
|
||||||
var names_to_mangle = [];
|
var names_to_mangle = [];
|
||||||
var unmangleable = [];
|
var unmangleable = [];
|
||||||
var to_keep = {};
|
|
||||||
|
|
||||||
// step 1: find candidates to mangle
|
// step 1: find candidates to mangle
|
||||||
ast.walk(new TreeWalker(function(node){
|
ast.walk(new TreeWalker(function(node){
|
||||||
if (node instanceof AST_ObjectKeyVal) {
|
if (node instanceof AST_ObjectKeyVal) {
|
||||||
add(node.key, keep_quoted && node.quote);
|
add(node.key);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_ObjectProperty) {
|
else if (node instanceof AST_ObjectProperty) {
|
||||||
// setter or getter, since KeyVal is handled above
|
// setter or getter, since KeyVal is handled above
|
||||||
@@ -137,18 +165,14 @@ function mangle_properties(ast, options) {
|
|||||||
add(node.property);
|
add(node.property);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_Sub) {
|
else if (node instanceof AST_Sub) {
|
||||||
addStrings(node.property, keep_quoted);
|
addStrings(node.property, add);
|
||||||
}
|
|
||||||
else if (node instanceof AST_ConciseMethod) {
|
|
||||||
add(node.name.name);
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// step 2: transform the tree, renaming properties
|
// step 2: transform the tree, renaming properties
|
||||||
return ast.transform(new TreeTransformer(function(node){
|
return ast.transform(new TreeTransformer(function(node){
|
||||||
if (node instanceof AST_ObjectKeyVal) {
|
if (node instanceof AST_ObjectKeyVal) {
|
||||||
if (!(keep_quoted && node.quote))
|
node.key = mangle(node.key);
|
||||||
node.key = mangle(node.key);
|
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_ObjectProperty) {
|
else if (node instanceof AST_ObjectProperty) {
|
||||||
// setter or getter
|
// setter or getter
|
||||||
@@ -157,27 +181,9 @@ function mangle_properties(ast, options) {
|
|||||||
else if (node instanceof AST_Dot) {
|
else if (node instanceof AST_Dot) {
|
||||||
node.property = mangle(node.property);
|
node.property = mangle(node.property);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_Sub) {
|
else if (!options.keep_quoted && node instanceof AST_Sub) {
|
||||||
if (!keep_quoted)
|
node.property = mangleStrings(node.property);
|
||||||
node.property = mangleStrings(node.property);
|
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_ConciseMethod) {
|
|
||||||
if (should_mangle(node.name.name)) {
|
|
||||||
node.name.name = mangle(node.name.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// else if (node instanceof AST_String) {
|
|
||||||
// if (should_mangle(node.value)) {
|
|
||||||
// AST_Node.warn(
|
|
||||||
// "Found \"{prop}\" property candidate for mangling in an arbitrary string [{file}:{line},{col}]", {
|
|
||||||
// file : node.start.file,
|
|
||||||
// line : node.start.line,
|
|
||||||
// col : node.start.col,
|
|
||||||
// prop : node.value
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// only function declarations after this line
|
// only function declarations after this line
|
||||||
@@ -193,19 +199,13 @@ function mangle_properties(ast, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function should_mangle(name) {
|
function should_mangle(name) {
|
||||||
if (keep_quoted && name in to_keep) return false;
|
|
||||||
if (regex && !regex.test(name)) return false;
|
if (regex && !regex.test(name)) return false;
|
||||||
if (reserved.indexOf(name) >= 0) return false;
|
if (reserved.indexOf(name) >= 0) return false;
|
||||||
return cache.props.has(name)
|
return cache.props.has(name)
|
||||||
|| names_to_mangle.indexOf(name) >= 0;
|
|| names_to_mangle.indexOf(name) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function add(name, keep) {
|
function add(name) {
|
||||||
if (keep) {
|
|
||||||
to_keep[name] = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (can_mangle(name))
|
if (can_mangle(name))
|
||||||
push_uniq(names_to_mangle, name);
|
push_uniq(names_to_mangle, name);
|
||||||
|
|
||||||
@@ -225,19 +225,16 @@ function mangle_properties(ast, options) {
|
|||||||
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
||||||
var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
|
var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
|
||||||
|
|
||||||
if (can_mangle(debug_mangled) && !(keep_quoted && debug_mangled in to_keep)) {
|
if (can_mangle(debug_mangled)) {
|
||||||
mangled = debug_mangled;
|
mangled = debug_mangled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// either debug mode is off, or it is on and we could not use the mangled name
|
// either debug mode is off, or it is on and we could not use the mangled name
|
||||||
if (!mangled) {
|
if (!mangled) {
|
||||||
// Note: `can_mangle()` does not check if the name collides with the `to_keep` set
|
|
||||||
// (filled with quoted properties when `keep_quoted` is set). Make sure we add this
|
|
||||||
// check so we don't collide with a quoted name.
|
|
||||||
do {
|
do {
|
||||||
mangled = base54(++cache.cname);
|
mangled = base54(++cache.cname);
|
||||||
} while (!can_mangle(mangled) || keep_quoted && mangled in to_keep);
|
} while (!can_mangle(mangled));
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.props.set(name, mangled);
|
cache.props.set(name, mangled);
|
||||||
@@ -245,32 +242,6 @@ function mangle_properties(ast, options) {
|
|||||||
return mangled;
|
return mangled;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addStrings(node, keep) {
|
|
||||||
var out = {};
|
|
||||||
try {
|
|
||||||
(function walk(node){
|
|
||||||
node.walk(new TreeWalker(function(node){
|
|
||||||
if (node instanceof AST_Sequence) {
|
|
||||||
walk(node.expressions[node.expressions.length - 1]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof AST_String) {
|
|
||||||
add(node.value, keep);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof AST_Conditional) {
|
|
||||||
walk(node.consequent);
|
|
||||||
walk(node.alternative);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
throw out;
|
|
||||||
}));
|
|
||||||
})(node);
|
|
||||||
} catch(ex) {
|
|
||||||
if (ex !== out) throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function mangleStrings(node) {
|
function mangleStrings(node) {
|
||||||
return node.transform(new TreeTransformer(function(node){
|
return node.transform(new TreeTransformer(function(node){
|
||||||
if (node instanceof AST_Sequence) {
|
if (node instanceof AST_Sequence) {
|
||||||
|
|||||||
20
lib/scope.js
20
lib/scope.js
@@ -116,7 +116,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
if (node.is_block_scope()) {
|
if (node.is_block_scope()) {
|
||||||
var save_scope = scope;
|
var save_scope = scope;
|
||||||
scope = new AST_Scope(node);
|
node.block_scope = scope = new AST_Scope(node);
|
||||||
scope.init_scope_vars(save_scope);
|
scope.init_scope_vars(save_scope);
|
||||||
if (!(node instanceof AST_Scope)) {
|
if (!(node instanceof AST_Scope)) {
|
||||||
scope.uses_with = save_scope.uses_with;
|
scope.uses_with = save_scope.uses_with;
|
||||||
@@ -203,6 +203,21 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
|| node instanceof AST_SymbolLet
|
|| node instanceof AST_SymbolLet
|
||||||
|| node instanceof AST_SymbolConst) {
|
|| node instanceof AST_SymbolConst) {
|
||||||
var def = ((node instanceof AST_SymbolBlockDeclaration) ? scope : defun).def_variable(node);
|
var def = ((node instanceof AST_SymbolBlockDeclaration) ? scope : defun).def_variable(node);
|
||||||
|
if (!all(def.orig, function(sym) {
|
||||||
|
if (sym === node) return true;
|
||||||
|
if (node instanceof AST_SymbolBlockDeclaration) {
|
||||||
|
return sym instanceof AST_SymbolLambda;
|
||||||
|
}
|
||||||
|
return !(sym instanceof AST_SymbolLet || sym instanceof AST_SymbolConst);
|
||||||
|
})) {
|
||||||
|
js_error(
|
||||||
|
node.name + " redeclared",
|
||||||
|
node.start.file,
|
||||||
|
node.start.line,
|
||||||
|
node.start.col,
|
||||||
|
node.start.pos
|
||||||
|
);
|
||||||
|
}
|
||||||
if (!(node instanceof AST_SymbolFunarg)) mark_export(def, 2);
|
if (!(node instanceof AST_SymbolFunarg)) mark_export(def, 2);
|
||||||
def.destructuring = in_destructuring;
|
def.destructuring = in_destructuring;
|
||||||
if (defun !== scope) {
|
if (defun !== scope) {
|
||||||
@@ -300,6 +315,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
ref.reference(options);
|
ref.reference(options);
|
||||||
});
|
});
|
||||||
node.thedef = def;
|
node.thedef = def;
|
||||||
|
node.reference(options);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@@ -357,7 +373,7 @@ AST_IterationStatement.DEFMETHOD("is_block_scope", return_true);
|
|||||||
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
||||||
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
||||||
this.uses_arguments = false;
|
this.uses_arguments = false;
|
||||||
this.def_variable(new AST_SymbolConst({
|
this.def_variable(new AST_SymbolFunarg({
|
||||||
name: "arguments",
|
name: "arguments",
|
||||||
start: this.start,
|
start: this.start,
|
||||||
end: this.end
|
end: this.end
|
||||||
|
|||||||
@@ -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.26",
|
"version": "3.0.28",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ no_leading_parentheses: {
|
|||||||
|
|
||||||
async_identifiers: {
|
async_identifiers: {
|
||||||
options = {
|
options = {
|
||||||
arrows: true,
|
unsafe_arrows: true,
|
||||||
ecma: 6,
|
ecma: 6,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -237,7 +237,7 @@ async_identifiers: {
|
|||||||
|
|
||||||
async_function_expression: {
|
async_function_expression: {
|
||||||
options = {
|
options = {
|
||||||
arrows: true,
|
unsafe_arrows: true,
|
||||||
ecma: 6,
|
ecma: 6,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -262,7 +262,7 @@ async_function_expression: {
|
|||||||
|
|
||||||
issue_27: {
|
issue_27: {
|
||||||
options = {
|
options = {
|
||||||
arrows: true,
|
unsafe_arrows: true,
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
ecma: 6,
|
ecma: 6,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -283,7 +283,7 @@ issue_27: {
|
|||||||
|
|
||||||
issue_2105_1: {
|
issue_2105_1: {
|
||||||
options = {
|
options = {
|
||||||
arrows: true,
|
unsafe_arrows: true,
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
ecma: 6,
|
ecma: 6,
|
||||||
inline: true,
|
inline: true,
|
||||||
@@ -501,7 +501,7 @@ issue_485_crashing_1530: {
|
|||||||
|
|
||||||
issue_2084: {
|
issue_2084: {
|
||||||
options = {
|
options = {
|
||||||
arrows: true,
|
unsafe_arrows: true,
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
ecma: 6,
|
ecma: 6,
|
||||||
@@ -577,6 +577,7 @@ concise_methods_with_computed_property2: {
|
|||||||
async_object_literal: {
|
async_object_literal: {
|
||||||
options = {
|
options = {
|
||||||
arrows: true,
|
arrows: true,
|
||||||
|
unsafe_arrows: true,
|
||||||
ecma: 6,
|
ecma: 6,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
}
|
}
|
||||||
@@ -597,3 +598,35 @@ async_object_literal: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2271: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
unsafe_arrows: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var Foo = function() {};
|
||||||
|
Foo.prototype.set = function(value) {
|
||||||
|
this.value = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
Foo.prototype.print = function() {
|
||||||
|
console.log(this.value);
|
||||||
|
}
|
||||||
|
new Foo().set("PASS").print();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var Foo = function() {};
|
||||||
|
Foo.prototype.set = function(value) {
|
||||||
|
this.value = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
Foo.prototype.print = function() {
|
||||||
|
console.log(this.value);
|
||||||
|
}
|
||||||
|
new Foo().set("PASS").print();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ ascii_only_true: {
|
|||||||
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\v\\f\\r\\x0e\\x0f"+"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f"+\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\'}'
|
expect_exact: 'function f(){return"\\x000\\x001\\x007\\x008\\0"+"\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\v\\f\\r\\x0e\\x0f"+"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f"+\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\'}'
|
||||||
}
|
}
|
||||||
|
|
||||||
ascii_only_false: {
|
ascii_only_false: {
|
||||||
@@ -31,5 +31,5 @@ ascii_only_false: {
|
|||||||
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
expect_exact: 'function f(){return"\\x000\\x001\\x007\\x008\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2548,3 +2548,71 @@ duplicate_argname: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2250_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(x) {
|
||||||
|
if (x) {
|
||||||
|
const a = foo();
|
||||||
|
x(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function g(x) {
|
||||||
|
if (x) {
|
||||||
|
let a = foo();
|
||||||
|
x(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function h(x) {
|
||||||
|
if (x) {
|
||||||
|
var a = foo();
|
||||||
|
x(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(x) {
|
||||||
|
x && x(foo());
|
||||||
|
}
|
||||||
|
function g(x) {
|
||||||
|
x && x(foo());
|
||||||
|
}
|
||||||
|
function h(x) {
|
||||||
|
x && x(foo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2250_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
{
|
||||||
|
const foo = function(){};
|
||||||
|
foo(bar());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let foo = function(){};
|
||||||
|
foo(bar());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var foo = function(){};
|
||||||
|
foo(bar());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
bar();
|
||||||
|
bar();
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ concat_1: {
|
|||||||
var c = 1 + x() + 2 + "boo";
|
var c = 1 + x() + 2 + "boo";
|
||||||
var d = 1 + x() + 2 + 3 + "boo";
|
var d = 1 + x() + 2 + 3 + "boo";
|
||||||
var e = 1 + x() + 2 + "X3boo";
|
var e = 1 + x() + 2 + "X3boo";
|
||||||
var f = "\x00360\08\0";
|
var f = "\x00360\x008\0";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,10 +65,10 @@ nested_destructuring_objects: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
const [{a},b] = c;
|
const [{a},b] = c;
|
||||||
let [{a},b] = c;
|
let [{d},e] = f;
|
||||||
var [{a},b] = c;
|
var [{g},h] = i;
|
||||||
}
|
}
|
||||||
expect_exact: 'const[{a},b]=c;let[{a},b]=c;var[{a},b]=c;';
|
expect_exact: 'const[{a},b]=c;let[{d},e]=f;var[{g},h]=i;';
|
||||||
}
|
}
|
||||||
|
|
||||||
destructuring_constdef_in_loops: {
|
destructuring_constdef_in_loops: {
|
||||||
@@ -274,8 +274,8 @@ reduce_vars: {
|
|||||||
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
|
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
|
||||||
({aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}});
|
({aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}});
|
||||||
const [{a},b] = c;
|
const [{a},b] = c;
|
||||||
let [{a},b] = c;
|
let [{d},e] = f;
|
||||||
var [{a},b] = c;
|
var [{g},h] = i;
|
||||||
[{a},b] = c;
|
[{a},b] = c;
|
||||||
for (const [x,y] in pairs);
|
for (const [x,y] in pairs);
|
||||||
for (let [x,y] in pairs);
|
for (let [x,y] in pairs);
|
||||||
@@ -292,8 +292,8 @@ reduce_vars: {
|
|||||||
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
|
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
|
||||||
({aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}});
|
({aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}});
|
||||||
const [{a},b] = c;
|
const [{a},b] = c;
|
||||||
let [{a},b] = c;
|
let [{d},e] = f;
|
||||||
var [{a},b] = c;
|
var [{g},h] = i;
|
||||||
[{a},b] = c;
|
[{a},b] = c;
|
||||||
for (const [x,y] in pairs);
|
for (const [x,y] in pairs);
|
||||||
for (let [x,y] in pairs);
|
for (let [x,y] in pairs);
|
||||||
|
|||||||
@@ -211,13 +211,13 @@ export_statement: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
export default 1 + 2;
|
export default 1 + 2;
|
||||||
export var foo = 4;
|
export var a = 4;
|
||||||
export let foo = 6;
|
export let b = 6;
|
||||||
export const foo = 6;
|
export const c = 6;
|
||||||
export function foo() {};
|
export function d() {};
|
||||||
export class foo { };
|
export class e {};
|
||||||
}
|
}
|
||||||
expect_exact: "export default 3;export var foo=4;export let foo=6;export const foo=6;export function foo(){};export class foo{};"
|
expect_exact: "export default 3;export var a=4;export let b=6;export const c=6;export function d(){};export class e{};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_default_object_expression: {
|
export_default_object_expression: {
|
||||||
@@ -695,3 +695,112 @@ export_default_class_decl: {
|
|||||||
}
|
}
|
||||||
expect_exact: "export default class Car{};export class Cab{};"
|
expect_exact: "export default class Car{};export class Cab{};"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object_rest_spread: {
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var { w: w1, ...V } = { w: 7, x: 1, y: 2 }; console.log(w1, V);
|
||||||
|
let { w: w2, ...L } = { w: 8, x: 3, y: 4 }; console.log(w2, L);
|
||||||
|
const { w: w3, ...C } = { w: 9, x: 5, y: 6 }; console.log(w3, C);
|
||||||
|
|
||||||
|
let b;
|
||||||
|
({ b, ...V } = { a: 1, b: 2, c: 3 }); console.log(V);
|
||||||
|
({ b, ...L } = { a: 4, b: 5, c: 6 }); console.log(L);
|
||||||
|
|
||||||
|
(function({ y, ...p }){ console.log(p); })({ x: 1, y: 2, z: 3 });
|
||||||
|
(({ y, ...p }) => { console.log(p); })({ x: 4, y: 5, z: 6 });
|
||||||
|
|
||||||
|
const T = { a: 1, b: 2 }; console.log({ ...T, w: 0, ...{}, ...L, ...{K: 9} });
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var { w: o, ...l } = { w: 7, x: 1, y: 2 }; console.log(o, l);
|
||||||
|
let { w: c, ...n } = { w: 8, x: 3, y: 4 }; console.log(c, n);
|
||||||
|
const { w: e, ...s } = { w: 9, x: 5, y: 6 }; console.log(e, s);
|
||||||
|
|
||||||
|
let g;
|
||||||
|
({ b: g, ...l } = { a: 1, b: 2, c: 3 }); console.log(l);
|
||||||
|
({ b: g, ...n } = { a: 4, b: 5, c: 6 }); console.log(n);
|
||||||
|
|
||||||
|
(function({ y: o, ...l }) { console.log(l); })({ x: 1, y: 2, z: 3 });
|
||||||
|
(({ y: o, ...l }) => { console.log(l); })({ x: 4, y: 5, z: 6 });
|
||||||
|
|
||||||
|
const w = { a: 1, b: 2 }; console.log({ ...w, w: 0, ...{}, ...n, ...{ K: 9 } });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object_spread_unsafe: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o1 = { x: 1, y: 2 };
|
||||||
|
var o2 = { x: 3, z: 4 };
|
||||||
|
var cloned = { ...o1 };
|
||||||
|
var merged = { ...o1, ...o2 };
|
||||||
|
console.log(cloned, merged);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = { x: 1, y: 2 }, l = { ...o }, x = { ...o, ...{ x: 3, z: 4 } };
|
||||||
|
console.log(l, x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
array_spread_of_sequence: {
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [1];
|
||||||
|
console.log([...(a, a)]);
|
||||||
|
console.log([...a, a]);
|
||||||
|
console.log([...(a || a)]);
|
||||||
|
console.log([...a || a]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = [1];
|
||||||
|
console.log([...(o, o)]);
|
||||||
|
console.log([...o, o]);
|
||||||
|
console.log([...o || o]);
|
||||||
|
console.log([...o || o]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"[ 1 ]",
|
||||||
|
"[ 1, [ 1 ] ]",
|
||||||
|
"[ 1 ]",
|
||||||
|
"[ 1 ]",
|
||||||
|
]
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
object_spread_of_sequence: {
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = {x: 1};
|
||||||
|
console.log({ ...(a, a) });
|
||||||
|
console.log({ ...a, a });
|
||||||
|
console.log({ ...(a || a) });
|
||||||
|
console.log({ ...a || a });
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = { x: 1 };
|
||||||
|
console.log({ ...(o, o) });
|
||||||
|
console.log({ ...o, a: o });
|
||||||
|
console.log({ ...o || o });
|
||||||
|
console.log({ ...o || o });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
issue_1321_no_debug: {
|
issue_1321_no_debug: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: true
|
properties: {
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -10,17 +12,19 @@ issue_1321_no_debug: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.o = 1;
|
x.x = 1;
|
||||||
x["a"] = 2 * x.o;
|
x["a"] = 2 * x.x;
|
||||||
console.log(x.o, x["a"]);
|
console.log(x.x, x["a"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1321_debug: {
|
issue_1321_debug: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: true,
|
properties: {
|
||||||
debug: ""
|
debug: "",
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -30,16 +34,18 @@ issue_1321_debug: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.o = 1;
|
x.x = 1;
|
||||||
x["_$foo$_"] = 2 * x.o;
|
x["_$foo$_"] = 2 * x.x;
|
||||||
console.log(x.o, x["_$foo$_"]);
|
console.log(x.x, x["_$foo$_"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1321_with_quoted: {
|
issue_1321_with_quoted: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: false
|
properties: {
|
||||||
|
keep_quoted: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -49,9 +55,9 @@ issue_1321_with_quoted: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.o = 1;
|
x.x = 1;
|
||||||
x["x"] = 2 * x.o;
|
x["o"] = 2 * x.x;
|
||||||
console.log(x.o, x["x"]);
|
console.log(x.x, x["o"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
mangle_props: {
|
mangle_props: {
|
||||||
mangle_props = {}
|
mangle = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
var obj = {
|
var obj = {
|
||||||
undefined: 1,
|
undefined: 1,
|
||||||
@@ -54,10 +56,12 @@ mangle_props: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
numeric_literal: {
|
numeric_literal: {
|
||||||
|
mangle = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
}
|
}
|
||||||
mangle_props = {}
|
|
||||||
input: {
|
input: {
|
||||||
var obj = {
|
var obj = {
|
||||||
0: 0,
|
0: 0,
|
||||||
|
|||||||
@@ -36,9 +36,10 @@ compress_new_function_with_destruct: {
|
|||||||
compress_new_function_with_destruct_arrows: {
|
compress_new_function_with_destruct_arrows: {
|
||||||
options = {
|
options = {
|
||||||
arrows: true,
|
arrows: true,
|
||||||
|
unsafe_arrows: true,
|
||||||
unsafe: true,
|
unsafe: true,
|
||||||
unsafe_Func: true,
|
unsafe_Func: true,
|
||||||
ecma: 6
|
ecma: 6,
|
||||||
}
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
ecma: 6
|
ecma: 6
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
dont_reuse_prop: {
|
dont_reuse_prop: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
regex: /asd/
|
properties: {
|
||||||
|
regex: /asd/,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"aaaaaaaaaabbbbb";
|
"aaaaaaaaaabbbbb";
|
||||||
@@ -20,8 +22,10 @@ dont_reuse_prop: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unmangleable_props_should_always_be_reserved: {
|
unmangleable_props_should_always_be_reserved: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
regex: /asd/
|
properties: {
|
||||||
|
regex: /asd/,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"aaaaaaaaaabbbbb";
|
"aaaaaaaaaabbbbb";
|
||||||
|
|||||||
@@ -284,9 +284,11 @@ concise_methods_with_various_property_names: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
concise_methods_and_mangle_props: {
|
concise_methods_and_mangle_props: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
regex: /_/
|
properties: {
|
||||||
};
|
regex: /_/,
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
function x() {
|
function x() {
|
||||||
obj = {
|
obj = {
|
||||||
|
|||||||
@@ -142,11 +142,11 @@ destructuring_arguments_3: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function fn3({x: {y: {z: {} = 42}}}) {}
|
function fn3({x: {y: {z: {} = 42}}}) {}
|
||||||
const { cover = (function () {}), xCover = (0, function() {}) } = {};
|
const { a = (function () {}), b = (0, function() {}) } = {};
|
||||||
let { cover = (function () {}), xCover = (0, function() {}) } = {};
|
let { c = (function () {}), d = (0, function() {}) } = {};
|
||||||
var { cover = (function () {}), xCover = (0, function() {}) } = {};
|
var { e = (function () {}), f = (0, function() {}) } = {};
|
||||||
}
|
}
|
||||||
expect_exact: "function fn3({x:{y:{z:{}=42}}}){}const{cover=function(){},xCover=(0,function(){})}={};let{cover=function(){},xCover=(0,function(){})}={};var{cover=function(){},xCover=(0,function(){})}={};"
|
expect_exact: "function fn3({x:{y:{z:{}=42}}}){}const{a=function(){},b=(0,function(){})}={};let{c=function(){},d=(0,function(){})}={};var{e=function(){},f=(0,function(){})}={};"
|
||||||
}
|
}
|
||||||
|
|
||||||
default_arguments: {
|
default_arguments: {
|
||||||
|
|||||||
@@ -128,9 +128,11 @@ evaluate_string_length: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mangle_properties: {
|
mangle_properties: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: false
|
properties: {
|
||||||
};
|
keep_quoted: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a.color = "red";
|
a.color = "red";
|
||||||
@@ -139,11 +141,11 @@ mangle_properties: {
|
|||||||
a['run']({color: "blue", foo: "baz"});
|
a['run']({color: "blue", foo: "baz"});
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
a["o"] = "bar";
|
a["a"] = "bar";
|
||||||
a.a = "red";
|
a.b = "red";
|
||||||
x = {r: 10};
|
x = {o: 10};
|
||||||
a.b(x.r, a.o);
|
a.r(x.o, a.a);
|
||||||
a['b']({a: "blue", o: "baz"});
|
a['r']({b: "blue", a: "baz"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,9 +153,11 @@ mangle_unquoted_properties: {
|
|||||||
options = {
|
options = {
|
||||||
properties: false
|
properties: false
|
||||||
}
|
}
|
||||||
mangle_props = {
|
mangle = {
|
||||||
builtins: true,
|
properties: {
|
||||||
keep_quoted: true
|
builtins: true,
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
@@ -182,24 +186,26 @@ mangle_unquoted_properties: {
|
|||||||
function f1() {
|
function f1() {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a.color = "red";
|
a.color = "red";
|
||||||
a.o = 2;
|
a.r = 2;
|
||||||
x = {"bar": 10, f: 7};
|
x = {"bar": 10, b: 7};
|
||||||
a.f = 9;
|
a.b = 9;
|
||||||
}
|
}
|
||||||
function f2() {
|
function f2() {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
a['color'] = "red";
|
a['color'] = "red";
|
||||||
x = {bar: 10, f: 7};
|
x = {bar: 10, b: 7};
|
||||||
a.f = 9;
|
a.b = 9;
|
||||||
a.o = 3;
|
a.r = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mangle_debug: {
|
mangle_debug: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
debug: ""
|
properties: {
|
||||||
};
|
debug: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
x = { baz: "ban" };
|
x = { baz: "ban" };
|
||||||
@@ -211,9 +217,11 @@ mangle_debug: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mangle_debug_true: {
|
mangle_debug_true: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
debug: true
|
properties: {
|
||||||
};
|
debug: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
x = { baz: "ban" };
|
x = { baz: "ban" };
|
||||||
@@ -225,9 +233,11 @@ mangle_debug_true: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mangle_debug_suffix: {
|
mangle_debug_suffix: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
debug: "XYZ"
|
properties: {
|
||||||
};
|
debug: "XYZ",
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
x = { baz: "ban" };
|
x = { baz: "ban" };
|
||||||
@@ -242,11 +252,13 @@ mangle_debug_suffix_keep_quoted: {
|
|||||||
options = {
|
options = {
|
||||||
properties: false
|
properties: false
|
||||||
}
|
}
|
||||||
mangle_props = {
|
mangle = {
|
||||||
builtins: true,
|
properties: {
|
||||||
keep_quoted: true,
|
builtins: true,
|
||||||
debug: "XYZ",
|
debug: "XYZ",
|
||||||
reserved: []
|
keep_quoted: true,
|
||||||
|
reserved: [],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
@@ -870,3 +882,85 @@ issue_2208_9: {
|
|||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
methods_keep_quoted_true: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
ecma: 6,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
properties: {
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
class C { "Quoted"(){} Unquoted(){} }
|
||||||
|
f1({ "Quoted"(){}, Unquoted(){}, "Prop": 3 });
|
||||||
|
f2({ "Quoted": function(){} });
|
||||||
|
f3({ "Quoted": ()=>{} });
|
||||||
|
}
|
||||||
|
expect_exact: "class C{Quoted(){}o(){}}f1({Quoted(){},o(){},Prop:3});f2({Quoted(){}});f3({Quoted(){}});"
|
||||||
|
}
|
||||||
|
|
||||||
|
methods_keep_quoted_false: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
ecma: 6,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
properties: {
|
||||||
|
keep_quoted: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
class C { "Quoted"(){} Unquoted(){} }
|
||||||
|
f1({ "Quoted"(){}, Unquoted(){}, "Prop": 3 });
|
||||||
|
f2({ "Quoted": function(){} });
|
||||||
|
f3({ "Quoted": ()=>{} });
|
||||||
|
}
|
||||||
|
expect_exact: "class C{o(){}d(){}}f1({o(){},d(){},e:3});f2({o(){}});f3({o(){}});"
|
||||||
|
}
|
||||||
|
|
||||||
|
methods_keep_quoted_from_dead_code: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
booleans: true,
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
properties: {
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
class C { Quoted(){} Unquoted(){} }
|
||||||
|
f1({ Quoted(){}, Unquoted(){}, "Prop": 3 });
|
||||||
|
f2({ Quoted: function(){} });
|
||||||
|
f3({ Quoted: ()=>{} });
|
||||||
|
0 && obj["Quoted"];
|
||||||
|
}
|
||||||
|
expect_exact: "class C{Quoted(){}o(){}}f1({Quoted(){},o(){},Prop:3});f2({Quoted(){}});f3({Quoted(){}});"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2256: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
properties: {
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({ "keep": 1 });
|
||||||
|
g.keep = g.change;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
g.keep = g.g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -385,3 +385,76 @@ set_mutable_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2265_1: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({ ...{} }).p;
|
||||||
|
({ ...g }).p;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
({ ...g }).p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2265_2: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = {
|
||||||
|
get b() {
|
||||||
|
throw 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
({...a}).b;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = {
|
||||||
|
get b() {
|
||||||
|
throw 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
({...a}).b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2265_3: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = {
|
||||||
|
set b() {
|
||||||
|
throw 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
({...a}).b;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2265_4: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = { b: 1 };
|
||||||
|
({...a}).b;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
}
|
||||||
|
|||||||
@@ -325,3 +325,69 @@ issue_2120_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2254_1: {
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"eeeeee";
|
||||||
|
try {
|
||||||
|
console.log(f("PASS"));
|
||||||
|
} catch (e) {}
|
||||||
|
function f(s) {
|
||||||
|
try {
|
||||||
|
throw "FAIL";
|
||||||
|
} catch (e) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"eeeeee";
|
||||||
|
try {
|
||||||
|
console.log(f("PASS"));
|
||||||
|
} catch (e) {}
|
||||||
|
function f(e) {
|
||||||
|
try {
|
||||||
|
throw "FAIL";
|
||||||
|
} catch (t) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2254_2: {
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"eeeeee";
|
||||||
|
try {
|
||||||
|
console.log(f("PASS"));
|
||||||
|
} catch (e) {}
|
||||||
|
function f(s) {
|
||||||
|
try {
|
||||||
|
throw "FAIL";
|
||||||
|
} catch (e) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"eeeeee";
|
||||||
|
try {
|
||||||
|
console.log(f("PASS"));
|
||||||
|
} catch (e) {}
|
||||||
|
function f(t) {
|
||||||
|
try {
|
||||||
|
throw "FAIL";
|
||||||
|
} catch (e) {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ exports["defaults"] = defaults;
|
|||||||
exports["mangle_properties"] = mangle_properties;
|
exports["mangle_properties"] = mangle_properties;
|
||||||
exports["minify"] = minify;
|
exports["minify"] = minify;
|
||||||
exports["parse"] = parse;
|
exports["parse"] = parse;
|
||||||
|
exports["reserve_quoted_keys"] = reserve_quoted_keys;
|
||||||
exports["string_template"] = string_template;
|
exports["string_template"] = string_template;
|
||||||
exports["tokenizer"] = tokenizer;
|
exports["tokenizer"] = tokenizer;
|
||||||
exports["is_identifier"] = is_identifier;
|
exports["is_identifier"] = is_identifier;
|
||||||
|
|||||||
@@ -253,13 +253,19 @@ describe("Left-hand side expressions", function () {
|
|||||||
// Multiple spreads are not allowed in destructuring array
|
// Multiple spreads are not allowed in destructuring array
|
||||||
expect("[...a, ...b] = [1, 2, 3, 4]", "Spread must the be last element in destructuring array");
|
expect("[...a, ...b] = [1, 2, 3, 4]", "Spread must the be last element in destructuring array");
|
||||||
|
|
||||||
// Spread in obvious object pattern
|
// Array spread must be last in destructuring declaration
|
||||||
expect("({...a} = foo)", "Unexpected token: expand (...)");
|
expect("let [ ...x, a ] = o;", "Rest element must be last element");
|
||||||
|
|
||||||
|
// Only one spread per destructuring array declaration
|
||||||
|
expect("let [ a, ...x, ...y ] = o;", "Rest element must be last element");
|
||||||
|
|
||||||
// Spread in block should not be allowed
|
// Spread in block should not be allowed
|
||||||
expect("{...a} = foo", "Unexpected token: expand (...)");
|
expect("{...a} = foo", "Unexpected token: expand (...)");
|
||||||
|
|
||||||
// Not in standard yet
|
// Object spread must be last in destructuring declaration
|
||||||
expect("let foo = {bar: 42}, bar; bar = {...foo}", "Unexpected token: expand (...)");
|
expect("let { ...x, a } = o;", "Rest element must be last element");
|
||||||
|
|
||||||
|
// Only one spread per destructuring declaration
|
||||||
|
expect("let { a, ...x, ...y } = o;", "Rest element must be last element");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -124,6 +124,17 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(result.code,
|
assert.strictEqual(result.code,
|
||||||
'a["foo"]="bar",a.a="red",x={"bar":10};');
|
'a["foo"]="bar",a.a="red",x={"bar":10};');
|
||||||
});
|
});
|
||||||
|
it("Should not mangle quoted property within dead code", function() {
|
||||||
|
var result = Uglify.minify('({ "keep": 1 }); g.keep = g.change;', {
|
||||||
|
mangle: {
|
||||||
|
properties: {
|
||||||
|
keep_quoted: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, "g.keep=g.g;");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("inSourceMap", function() {
|
describe("inSourceMap", function() {
|
||||||
@@ -280,4 +291,34 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(result.code, "alert({bar:42});");
|
assert.strictEqual(result.code, "alert({bar:42});");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("duplicated block-scoped declarations", function() {
|
||||||
|
[
|
||||||
|
"let a=1;let a=2;",
|
||||||
|
"let a=1;var a=2;",
|
||||||
|
"var a=1;let a=2;",
|
||||||
|
"let[a]=[1];var a=2;",
|
||||||
|
"let a=1;var[a]=[2];",
|
||||||
|
"let[a]=[1];var[a]=[2];",
|
||||||
|
"const a=1;const a=2;",
|
||||||
|
"const a=1;var a=2;",
|
||||||
|
"var a=1;const a=2;",
|
||||||
|
"const[a]=[1];var a=2;",
|
||||||
|
"const a=1;var[a]=[2];",
|
||||||
|
"const[a]=[1];var[a]=[2];",
|
||||||
|
].forEach(function(code) {
|
||||||
|
it(code, function() {
|
||||||
|
var result = Uglify.minify(code, {
|
||||||
|
compress: false,
|
||||||
|
mangle: false
|
||||||
|
});
|
||||||
|
assert.strictEqual(result.error, undefined);
|
||||||
|
assert.strictEqual(result.code, code);
|
||||||
|
result = Uglify.minify(code);
|
||||||
|
var err = result.error;
|
||||||
|
assert.ok(err instanceof Error);
|
||||||
|
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: a redeclared");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -61,9 +61,9 @@ describe("String literals", function() {
|
|||||||
var tests = [
|
var tests = [
|
||||||
['"\\76";', ';">";'],
|
['"\\76";', ';">";'],
|
||||||
['"\\0"', '"\\0";'],
|
['"\\0"', '"\\0";'],
|
||||||
['"\\08"', '"\\08";'],
|
['"\\08"', '"\\x008";'],
|
||||||
['"\\008"', '"\\08";'],
|
['"\\008"', '"\\x008";'],
|
||||||
['"\\0008"', '"\\08";'],
|
['"\\0008"', '"\\x008";'],
|
||||||
['"use strict" === "use strict";\n"\\76";', '"use strict"==="use strict";">";'],
|
['"use strict" === "use strict";\n"\\76";', '"use strict"==="use strict";">";'],
|
||||||
['"use\\\n strict";\n"\\07";', ';"use strict";"\07";']
|
['"use\\\n strict";\n"\\07";', ';"use strict";"\07";']
|
||||||
];
|
];
|
||||||
@@ -75,8 +75,8 @@ describe("String literals", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should not throw error when digit is 8 or 9", function() {
|
it("Should not throw error when digit is 8 or 9", function() {
|
||||||
assert.equal(UglifyJS.parse('"use strict";"\\08"').print_to_string(), '"use strict";"\\08";');
|
assert.equal(UglifyJS.parse('"use strict";"\\08"').print_to_string(), '"use strict";"\\x008";');
|
||||||
assert.equal(UglifyJS.parse('"use strict";"\\09"').print_to_string(), '"use strict";"\\09";');
|
assert.equal(UglifyJS.parse('"use strict";"\\09"').print_to_string(), '"use strict";"\\x009";');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should not unescape unpaired surrogates", function() {
|
it("Should not unescape unpaired surrogates", function() {
|
||||||
|
|||||||
@@ -146,8 +146,9 @@ describe("Unicode", function() {
|
|||||||
|
|
||||||
if (semver.satisfies(process.version, ">=4")) {
|
if (semver.satisfies(process.version, ">=4")) {
|
||||||
it("Should not unescape unpaired surrogates", function() {
|
it("Should not unescape unpaired surrogates", function() {
|
||||||
|
this.timeout(5000);
|
||||||
var code = [];
|
var code = [];
|
||||||
for (var i = 0; i <= 0xFFFF; i++) {
|
for (var i = 0; i <= 0x20001; i++) {
|
||||||
code.push("\\u{" + i.toString(16) + "}");
|
code.push("\\u{" + i.toString(16) + "}");
|
||||||
}
|
}
|
||||||
code = '"' + code.join() + '"';
|
code = '"' + code.join() + '"';
|
||||||
@@ -162,7 +163,7 @@ describe("Unicode", function() {
|
|||||||
ecma: ecma
|
ecma: ecma
|
||||||
});
|
});
|
||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.ok(code.length > result.code.length);
|
if (ecma > 5) assert.ok(code.length > result.code.length);
|
||||||
assert.strictEqual(eval(code), eval(result.code));
|
assert.strictEqual(eval(code), eval(result.code));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -111,18 +111,22 @@ function run_compress_tests() {
|
|||||||
};
|
};
|
||||||
if (!options.warnings) options.warnings = true;
|
if (!options.warnings) options.warnings = true;
|
||||||
}
|
}
|
||||||
|
if (test.mangle && test.mangle.properties && test.mangle.properties.keep_quoted) {
|
||||||
|
var quoted_props = test.mangle.properties.reserved;
|
||||||
|
if (!Array.isArray(quoted_props)) quoted_props = [];
|
||||||
|
test.mangle.properties.reserved = quoted_props;
|
||||||
|
U.reserve_quoted_keys(input, quoted_props);
|
||||||
|
}
|
||||||
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 || test.mangle_props) {
|
if (test.mangle) {
|
||||||
U.base54.reset();
|
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.properties) {
|
||||||
if (test.mangle_props) {
|
output = U.mangle_properties(output, test.mangle.properties);
|
||||||
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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user