uglify-js
Advanced tools
Comparing version 3.11.6 to 3.12.0
123
lib/ast.js
@@ -417,4 +417,8 @@ /*********************************************************************** | ||
if (this.init.definitions.length != 1) throw new Error("init must have single declaration"); | ||
} else if (!(this.init instanceof AST_PropAccess || this.init instanceof AST_SymbolRef)) { | ||
throw new Error("init must be assignable"); | ||
} else { | ||
validate_destructured(this.init, function(node) { | ||
if (!(node instanceof AST_PropAccess || node instanceof AST_SymbolRef)) { | ||
throw new Error("init must be assignable: " + node.TYPE); | ||
} | ||
}); | ||
} | ||
@@ -500,9 +504,21 @@ must_be_expression(this, "object"); | ||
var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments length_read", { | ||
var AST_Lambda = DEFNODE("Lambda", "name argnames length_read uses_arguments", { | ||
$documentation: "Base class for functions", | ||
$propdoc: { | ||
name: "[AST_SymbolDeclaration?] the name of this function", | ||
argnames: "[AST_SymbolFunarg*] array of function arguments", | ||
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array" | ||
argnames: "[(AST_Destructured|AST_SymbolFunarg)*] array of function arguments and/or destructured literals", | ||
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array", | ||
}, | ||
each_argname: function(visit) { | ||
var tw = new TreeWalker(function(node) { | ||
if (node instanceof AST_DestructuredKeyVal) { | ||
node.value.walk(tw); | ||
return true; | ||
} | ||
if (node instanceof AST_SymbolFunarg) visit(node); | ||
}); | ||
this.argnames.forEach(function(argname) { | ||
argname.walk(tw); | ||
}); | ||
}, | ||
walk: function(visitor) { | ||
@@ -520,3 +536,5 @@ var node = this; | ||
this.argnames.forEach(function(node) { | ||
if (!(node instanceof AST_SymbolFunarg)) throw new Error("argnames must be AST_SymbolFunarg[]"); | ||
validate_destructured(node, function(node) { | ||
if (!(node instanceof AST_SymbolFunarg)) throw new Error("argnames must be AST_SymbolFunarg[]"); | ||
}); | ||
}); | ||
@@ -754,4 +772,6 @@ }, | ||
if (!(node instanceof AST_VarDef)) throw new Error("definitions must be AST_VarDef[]"); | ||
if (!(node.name instanceof AST_SymbolConst)) throw new Error("name must be AST_SymbolConst"); | ||
must_be_expression(node, "value"); | ||
validate_destructured(node.name, function(node) { | ||
if (!(node instanceof AST_SymbolConst)) throw new Error("name must be AST_SymbolConst"); | ||
}); | ||
if (node.value != null) must_be_expression(node, "value"); | ||
}); | ||
@@ -766,3 +786,5 @@ }, | ||
if (!(node instanceof AST_VarDef)) throw new Error("definitions must be AST_VarDef[]"); | ||
if (!(node.name instanceof AST_SymbolLet)) throw new Error("name must be AST_SymbolLet"); | ||
validate_destructured(node.name, function(node) { | ||
if (!(node instanceof AST_SymbolLet)) throw new Error("name must be AST_SymbolLet"); | ||
}); | ||
if (node.value != null) must_be_expression(node, "value"); | ||
@@ -778,3 +800,5 @@ }); | ||
if (!(node instanceof AST_VarDef)) throw new Error("definitions must be AST_VarDef[]"); | ||
if (!(node.name instanceof AST_SymbolVar)) throw new Error("name must be AST_SymbolVar"); | ||
validate_destructured(node.name, function(node) { | ||
if (!(node instanceof AST_SymbolVar)) throw new Error("name must be AST_SymbolVar"); | ||
}); | ||
if (node.value != null) must_be_expression(node, "value"); | ||
@@ -978,2 +1002,10 @@ }); | ||
if (this.operator.indexOf("=") < 0) throw new Error('operator must contain "="'); | ||
if (this.left instanceof AST_Destructured) { | ||
if (this.operator != "=") throw new Error("invalid destructuring operator: " + this.operator); | ||
validate_destructured(this.left, function(node) { | ||
if (!(node instanceof AST_PropAccess || node instanceof AST_SymbolRef)) { | ||
throw new Error("left must be assignable: " + node.TYPE); | ||
} | ||
}); | ||
} | ||
}, | ||
@@ -1002,2 +1034,73 @@ }, AST_Binary); | ||
var AST_Destructured = DEFNODE("Destructured", null, { | ||
$documentation: "Base class for destructured literal", | ||
}); | ||
function validate_destructured(node, check) { | ||
if (node instanceof AST_DestructuredArray) return node.elements.forEach(function(node) { | ||
if (!(node instanceof AST_Hole)) validate_destructured(node, check); | ||
}); | ||
if (node instanceof AST_DestructuredObject) return node.properties.forEach(function(prop) { | ||
validate_destructured(prop.value, check); | ||
}); | ||
check(node); | ||
} | ||
var AST_DestructuredArray = DEFNODE("DestructuredArray", "elements", { | ||
$documentation: "A destructured array literal", | ||
$propdoc: { | ||
elements: "[AST_Node*] array of elements", | ||
}, | ||
walk: function(visitor) { | ||
var node = this; | ||
visitor.visit(node, function() { | ||
node.elements.forEach(function(element) { | ||
element.walk(visitor); | ||
}); | ||
}); | ||
}, | ||
}, AST_Destructured); | ||
var AST_DestructuredKeyVal = DEFNODE("DestructuredKeyVal", "key value", { | ||
$documentation: "A key: value destructured property", | ||
$propdoc: { | ||
key: "[string|AST_Node] property name. For computed property this is an AST_Node.", | ||
value: "[AST_Node] property value", | ||
}, | ||
walk: function(visitor) { | ||
var node = this; | ||
visitor.visit(node, function() { | ||
if (node.key instanceof AST_Node) node.key.walk(visitor); | ||
node.value.walk(visitor); | ||
}); | ||
}, | ||
_validate: function() { | ||
if (typeof this.key != "string") { | ||
if (!(this.key instanceof AST_Node)) throw new Error("key must be string or AST_Node"); | ||
must_be_expression(this, "key"); | ||
} | ||
must_be_expression(this, "value"); | ||
}, | ||
}); | ||
var AST_DestructuredObject = DEFNODE("DestructuredObject", "properties", { | ||
$documentation: "A destructured object literal", | ||
$propdoc: { | ||
properties: "[AST_DestructuredKeyVal*] array of properties", | ||
}, | ||
walk: function(visitor) { | ||
var node = this; | ||
visitor.visit(node, function() { | ||
node.properties.forEach(function(prop) { | ||
prop.walk(visitor); | ||
}); | ||
}); | ||
}, | ||
_validate: function() { | ||
this.properties.forEach(function(node) { | ||
if (!(node instanceof AST_DestructuredKeyVal)) throw new Error("properties must be AST_DestructuredKeyVal[]"); | ||
}); | ||
}, | ||
}, AST_Destructured); | ||
var AST_Object = DEFNODE("Object", "properties", { | ||
@@ -1004,0 +1107,0 @@ $documentation: "An object literal", |
@@ -92,2 +92,3 @@ "use strict"; | ||
warnings: false, | ||
webkit: false, | ||
wrap: false, | ||
@@ -105,2 +106,3 @@ }, true); | ||
set_shorthand("toplevel", options, [ "compress", "mangle" ]); | ||
set_shorthand("webkit", options, [ "mangle", "output" ]); | ||
var quoted_props; | ||
@@ -116,2 +118,3 @@ if (options.mangle) { | ||
toplevel: false, | ||
webkit: false, | ||
}, true); | ||
@@ -118,0 +121,0 @@ if (options.mangle.properties) { |
@@ -59,2 +59,3 @@ /*********************************************************************** | ||
comments : false, | ||
galio : false, | ||
ie8 : false, | ||
@@ -73,2 +74,3 @@ indent_level : 4, | ||
source_map : null, | ||
v8 : false, | ||
webkit : false, | ||
@@ -504,7 +506,7 @@ width : 80, | ||
if (/comment[134]/.test(c.type)) { | ||
print("//" + c.value.replace(/[@#]__PURE__/g, ' ') + "\n"); | ||
print("//" + c.value.replace(/[@#]__PURE__/g, " ") + "\n"); | ||
indent(); | ||
last_nlb = true; | ||
} else if (c.type == "comment2") { | ||
print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/"); | ||
print("/*" + c.value.replace(/[@#]__PURE__/g, " ") + "*/"); | ||
last_nlb = false; | ||
@@ -563,6 +565,6 @@ } | ||
if (/comment[134]/.test(c.type)) { | ||
print("//" + c.value.replace(/[@#]__PURE__/g, ' ')); | ||
print("//" + c.value.replace(/[@#]__PURE__/g, " ")); | ||
need_newline_indented = true; | ||
} else if (c.type == "comment2") { | ||
print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/"); | ||
print("/*" + c.value.replace(/[@#]__PURE__/g, " ") + "*/"); | ||
need_space = true; | ||
@@ -617,3 +619,3 @@ } | ||
return stack[stack.length - 2 - (n || 0)]; | ||
} | ||
}, | ||
}; | ||
@@ -660,9 +662,3 @@ } | ||
function PARENS(nodetype, func) { | ||
if (Array.isArray(nodetype)) { | ||
nodetype.forEach(function(nodetype) { | ||
PARENS(nodetype, func); | ||
}); | ||
} else { | ||
nodetype.DEFMETHOD("needs_parens", func); | ||
} | ||
nodetype.DEFMETHOD("needs_parens", func); | ||
} | ||
@@ -676,7 +672,7 @@ | ||
if (!output.has_parens() && first_in_statement(output)) return true; | ||
if (output.option('webkit')) { | ||
if (output.option("webkit")) { | ||
var p = output.parent(); | ||
if (p instanceof AST_PropAccess && p.expression === this) return true; | ||
} | ||
if (output.option('wrap_iife')) { | ||
if (output.option("wrap_iife")) { | ||
var p = output.parent(); | ||
@@ -689,5 +685,6 @@ if (p instanceof AST_Call && p.expression === this) return true; | ||
// interpreted as a block of code. | ||
PARENS(AST_Object, function(output) { | ||
function needs_parens_obj(output) { | ||
return !output.has_parens() && first_in_statement(output); | ||
}); | ||
} | ||
PARENS(AST_Object, needs_parens_obj); | ||
@@ -712,2 +709,3 @@ PARENS(AST_Unary, function(output) { | ||
// { foo: (1, 2) }.foo ==> 2 | ||
|| p instanceof AST_DestructuredKeyVal | ||
|| p instanceof AST_ObjectProperty | ||
@@ -759,3 +757,3 @@ // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2 | ||
// https://bugs.webkit.org/show_bug.cgi?id=123506 | ||
if (output.option('webkit')) { | ||
if (output.option("webkit")) { | ||
var g = output.parent(1); | ||
@@ -783,9 +781,10 @@ return this.expression instanceof AST_Function | ||
var value = this.value; | ||
// https://github.com/mishoo/UglifyJS/issues/115 | ||
// https://github.com/mishoo/UglifyJS/pull/1009 | ||
return value < 0 || /^0/.test(make_num(value)); | ||
// https://github.com/mishoo/UglifyJS/issues/115 | ||
return value < 0 | ||
// https://github.com/mishoo/UglifyJS/pull/1009 | ||
|| output.option("galio") && /^0/.test(make_num(value)); | ||
} | ||
}); | ||
PARENS([ AST_Assign, AST_Conditional ], function(output) { | ||
function needs_parens_assign_cond(self, output) { | ||
var p = output.parent(); | ||
@@ -795,10 +794,21 @@ // 1 + (a = 2) + 3 → 6, side effect setting a = 2 | ||
// (a = func)() —or— new (a = Object)() | ||
if (p instanceof AST_Call) return p.expression === this; | ||
if (p instanceof AST_Call) return p.expression === self; | ||
// (a = foo) ? bar : baz | ||
if (p instanceof AST_Conditional) return p.condition === this; | ||
if (p instanceof AST_Conditional) return p.condition === self; | ||
// (a = foo)["prop"] —or— (a = foo).prop | ||
if (p instanceof AST_PropAccess) return p.expression === this; | ||
if (p instanceof AST_PropAccess) return p.expression === self; | ||
// !(a = false) → true | ||
if (p instanceof AST_Unary) return true; | ||
} | ||
PARENS(AST_Assign, function(output) { | ||
if (needs_parens_assign_cond(this, output)) return true; | ||
// v8 parser bug => workaround | ||
// f([1], [a] = []) => f([1], ([a] = [])) | ||
if (output.option("v8")) return this.left instanceof AST_Destructured; | ||
// ({ p: a } = o); | ||
if (this.left instanceof AST_DestructuredObject) return needs_parens_obj(output); | ||
}); | ||
PARENS(AST_Conditional, function(output) { | ||
return needs_parens_assign_cond(this, output); | ||
}); | ||
@@ -1289,2 +1299,34 @@ /* -----[ PRINTERS ]----- */ | ||
}); | ||
DEFPRINT(AST_DestructuredArray, function(output) { | ||
var a = this.elements, len = a.length; | ||
output.with_square(len > 0 ? function() { | ||
output.space(); | ||
a.forEach(function(exp, i) { | ||
if (i) output.comma(); | ||
exp.print(output); | ||
// If the final element is a hole, we need to make sure it | ||
// doesn't look like a trailing comma, by inserting an actual | ||
// trailing comma. | ||
if (i === len - 1 && exp instanceof AST_Hole) | ||
output.comma(); | ||
}); | ||
output.space(); | ||
} : noop); | ||
}); | ||
DEFPRINT(AST_DestructuredKeyVal, print_key_value); | ||
DEFPRINT(AST_DestructuredObject, function(output) { | ||
var props = this.properties; | ||
if (props.length > 0) output.with_block(function() { | ||
props.forEach(function(prop, i) { | ||
if (i) { | ||
output.print(","); | ||
output.newline(); | ||
} | ||
output.indent(); | ||
prop.print(output); | ||
}); | ||
output.newline(); | ||
}); | ||
else print_braced_empty(this, output); | ||
}); | ||
DEFPRINT(AST_Object, function(output) { | ||
@@ -1330,3 +1372,3 @@ var props = this.properties; | ||
DEFPRINT(AST_ObjectKeyVal, function(output) { | ||
function print_key_value(output) { | ||
var self = this; | ||
@@ -1336,3 +1378,4 @@ print_property_key(self, output); | ||
self.value.print(output); | ||
}); | ||
} | ||
DEFPRINT(AST_ObjectKeyVal, print_key_value); | ||
function print_accessor(type) { | ||
@@ -1501,2 +1544,3 @@ return function(output) { | ||
AST_Definitions, | ||
AST_Destructured, | ||
AST_Finally, | ||
@@ -1516,5 +1560,5 @@ AST_Jump, | ||
DEFMAP([ AST_ObjectProperty ], function(output) { | ||
DEFMAP([ AST_DestructuredKeyVal, AST_ObjectProperty ], function(output) { | ||
if (typeof this.key == "string") output.add_mapping(this.start, this.key); | ||
}); | ||
})(); |
103
lib/parse.js
@@ -976,2 +976,4 @@ /*********************************************************************** | ||
? (next(), const_(true)) | ||
: is("keyword", "let") | ||
? (next(), let_(true)) | ||
: is("keyword", "var") | ||
@@ -981,6 +983,6 @@ ? (next(), var_(true)) | ||
if (is("operator", "in")) { | ||
if (init instanceof AST_Var) { | ||
if (init instanceof AST_Definitions) { | ||
if (init.definitions.length > 1) | ||
croak("Only one variable declaration allowed in for..in loop", init.start.line, init.start.col, init.start.pos); | ||
} else if (!is_assignable(init)) { | ||
} else if (!(is_assignable(init) || (init = to_destructured(init)) instanceof AST_Destructured)) { | ||
croak("Invalid left-hand side in for..in loop", init.start.line, init.start.col, init.start.pos); | ||
@@ -1030,3 +1032,3 @@ } | ||
if (first) first = false; else expect(","); | ||
argnames.push(as_symbol(AST_SymbolFunarg)); | ||
argnames.push(maybe_destructured(AST_SymbolFunarg)); | ||
} | ||
@@ -1152,7 +1154,7 @@ next(); | ||
function vardefs(type, no_in, must_init) { | ||
function vardefs(type, no_in) { | ||
var a = []; | ||
for (;;) { | ||
var start = S.token; | ||
var name = as_symbol(type); | ||
var name = maybe_destructured(type); | ||
var value = null; | ||
@@ -1162,3 +1164,3 @@ if (is("operator", "=")) { | ||
value = expression(false, no_in); | ||
} else if (must_init) { | ||
} else if (!no_in && (type === AST_SymbolConst || name instanceof AST_Destructured)) { | ||
croak("Missing initializer in declaration"); | ||
@@ -1182,3 +1184,3 @@ } | ||
start : prev(), | ||
definitions : vardefs(AST_SymbolConst, no_in, true), | ||
definitions : vardefs(AST_SymbolConst, no_in), | ||
end : prev() | ||
@@ -1315,3 +1317,4 @@ }); | ||
function expr_list(closing, allow_trailing_comma, allow_empty) { | ||
function expr_list(closing, allow_trailing_comma, allow_empty, parser) { | ||
if (!parser) parser = expression; | ||
var first = true, a = []; | ||
@@ -1324,3 +1327,3 @@ while (!is("punc", closing)) { | ||
} else { | ||
a.push(expression(false)); | ||
a.push(parser()); | ||
} | ||
@@ -1460,2 +1463,50 @@ } | ||
function maybe_destructured(type) { | ||
var start = S.token; | ||
if (is("punc", "[")) { | ||
next(); | ||
return new AST_DestructuredArray({ | ||
start: start, | ||
elements: expr_list("]", !options.strict, true, function() { | ||
return maybe_destructured(type); | ||
}), | ||
end: prev(), | ||
}); | ||
} | ||
if (is("punc", "{")) { | ||
next(); | ||
var first = true, a = []; | ||
while (!is("punc", "}")) { | ||
if (first) first = false; else expect(","); | ||
// allow trailing comma | ||
if (!options.strict && is("punc", "}")) break; | ||
var key_start = S.token; | ||
var key = as_property_key(); | ||
if (!is("punc", ":") && key_start.type == "name") { | ||
a.push(new AST_DestructuredKeyVal({ | ||
start: key_start, | ||
key: key, | ||
value: _make_symbol(type, key_start), | ||
end: prev(), | ||
})); | ||
continue; | ||
} | ||
expect(":"); | ||
a.push(new AST_DestructuredKeyVal({ | ||
start: key_start, | ||
key: key, | ||
value: maybe_destructured(type), | ||
end: prev(), | ||
})); | ||
} | ||
next(); | ||
return new AST_DestructuredObject({ | ||
start: start, | ||
properties: a, | ||
end: prev(), | ||
}); | ||
} | ||
return as_symbol(type); | ||
} | ||
function mark_pure(call) { | ||
@@ -1590,2 +1641,34 @@ var start = call.start; | ||
function to_destructured(node) { | ||
if (node instanceof AST_Array) { | ||
var elements = node.elements.map(to_destructured); | ||
return all(elements, function(node) { | ||
return node instanceof AST_Destructured || node instanceof AST_Hole || is_assignable(node); | ||
}) ? new AST_DestructuredArray({ | ||
start: node.start, | ||
elements: elements, | ||
end: node.end, | ||
}) : node; | ||
} | ||
if (!(node instanceof AST_Object)) return node; | ||
var props = []; | ||
for (var i = 0; i < node.properties.length; i++) { | ||
var prop = node.properties[i]; | ||
if (!(prop instanceof AST_ObjectKeyVal)) return node; | ||
var value = to_destructured(prop.value); | ||
if (!(value instanceof AST_Destructured || is_assignable(value))) return node; | ||
props.push(new AST_DestructuredKeyVal({ | ||
start: prop.start, | ||
key: prop.key, | ||
value: value, | ||
end: prop.end, | ||
})); | ||
} | ||
return new AST_DestructuredObject({ | ||
start: node.start, | ||
properties: props, | ||
end: node.end, | ||
}); | ||
} | ||
var maybe_assign = function(no_in) { | ||
@@ -1595,3 +1678,3 @@ var start = S.token; | ||
if (is("operator") && ASSIGNMENT[val]) { | ||
if (is_assignable(left)) { | ||
if (is_assignable(left) || val == "=" && (left = to_destructured(left)) instanceof AST_Destructured) { | ||
next(); | ||
@@ -1598,0 +1681,0 @@ return new AST_Assign({ |
@@ -75,3 +75,3 @@ /*********************************************************************** | ||
} else { | ||
this.mangled_name = next_mangled_name(this.scope, options, this); | ||
this.mangled_name = next_mangled_name(this, options); | ||
} | ||
@@ -208,3 +208,13 @@ if (this.global && cache) { | ||
self.globals = new Dictionary(); | ||
var in_arg = []; | ||
var tw = new TreeWalker(function(node) { | ||
if (node instanceof AST_Lambda) { | ||
in_arg.push(node); | ||
node.argnames.forEach(function(argname) { | ||
argname.walk(tw); | ||
}); | ||
in_arg.pop(); | ||
walk_body(node, tw); | ||
return true; | ||
} | ||
if (node instanceof AST_LoopControl) { | ||
@@ -217,6 +227,20 @@ if (node.label) node.label.thedef.references.push(node); | ||
var sym = node.scope.find_variable(name); | ||
for (var i = in_arg.length; i > 0 && sym;) { | ||
i = in_arg.lastIndexOf(sym.scope, i - 1); | ||
if (i < 0) break; | ||
var decl = sym.orig[0]; | ||
if (decl instanceof AST_SymbolFunarg || decl instanceof AST_SymbolLambda) { | ||
node.in_arg = true; | ||
break; | ||
} | ||
sym = sym.scope.parent_scope.find_variable(name); | ||
} | ||
if (!sym) { | ||
sym = self.def_global(node); | ||
} else if (name == "arguments" && sym.scope instanceof AST_Lambda) { | ||
sym.scope.uses_arguments = true; | ||
if (!(tw.parent() instanceof AST_PropAccess)) { | ||
sym.scope.uses_arguments = "d"; | ||
} else if (!sym.scope.uses_arguments) { | ||
sym.scope.uses_arguments = true; | ||
} | ||
} | ||
@@ -414,3 +438,4 @@ if (name == "eval") { | ||
function next_mangled_name(scope, options, def) { | ||
function next_mangled_name(def, options) { | ||
var scope = def.scope; | ||
var in_use = names_in_use(scope, options); | ||
@@ -468,2 +493,3 @@ var holes = scope.cname_holes; | ||
toplevel : false, | ||
webkit : false, | ||
}); | ||
@@ -503,5 +529,20 @@ if (!Array.isArray(options.reserved)) options.reserved = []; | ||
if (node instanceof AST_BlockScope) { | ||
var to_mangle = []; | ||
if (options.webkit && node instanceof AST_IterationStatement && node.init instanceof AST_Let) { | ||
node.init.definitions.forEach(function(defn) { | ||
defn.name.match_symbol(function(sym) { | ||
if (!(sym instanceof AST_SymbolLet)) return; | ||
var def = sym.definition(); | ||
var scope = sym.scope.parent_scope; | ||
var redef = scope.def_variable(sym); | ||
sym.thedef = def; | ||
scope.to_mangle.push(redef); | ||
def.redefined = function() { | ||
return redef; | ||
}; | ||
}); | ||
}, true); | ||
} | ||
node.to_mangle = []; | ||
node.variables.each(function(def) { | ||
if (!defer_redef(def)) to_mangle.push(def); | ||
if (!defer_redef(def)) node.to_mangle.push(def); | ||
}); | ||
@@ -517,3 +558,3 @@ descend(); | ||
} | ||
to_mangle.forEach(mangle); | ||
node.to_mangle.forEach(mangle); | ||
return true; | ||
@@ -538,9 +579,15 @@ } | ||
function defer_redef(def, node) { | ||
function defer_redef(def) { | ||
var sym = def.orig[0]; | ||
var redef = def.redefined(); | ||
if (!redef) return false; | ||
if (!redef) { | ||
if (!(sym instanceof AST_SymbolConst)) return false; | ||
var scope = def.scope.resolve(); | ||
if (def.scope === scope) return false; | ||
redef = scope.def_variable(sym); | ||
scope.to_mangle.push(redef); | ||
} | ||
redefined.push(def); | ||
def.references.forEach(reference); | ||
var node = def.orig[0]; | ||
if (node instanceof AST_SymbolCatch || node instanceof AST_SymbolConst) reference(node); | ||
if (sym instanceof AST_SymbolCatch || sym instanceof AST_SymbolConst) reference(sym); | ||
return true; | ||
@@ -547,0 +594,0 @@ |
@@ -163,2 +163,12 @@ /*********************************************************************** | ||
}); | ||
DEF(AST_DestructuredArray, function(self, tw) { | ||
self.elements = do_list(self.elements, tw); | ||
}); | ||
DEF(AST_DestructuredKeyVal, function(self, tw) { | ||
if (self.key instanceof AST_Node) self.key = self.key.transform(tw); | ||
self.value = self.value.transform(tw); | ||
}); | ||
DEF(AST_DestructuredObject, function(self, tw) { | ||
self.properties = do_list(self.properties, tw); | ||
}); | ||
DEF(AST_Object, function(self, tw) { | ||
@@ -165,0 +175,0 @@ self.properties = do_list(self.properties, tw); |
@@ -6,3 +6,3 @@ { | ||
"license": "BSD-2-Clause", | ||
"version": "3.11.6", | ||
"version": "3.12.0", | ||
"engines": { | ||
@@ -9,0 +9,0 @@ "node": ">=0.8.0" |
@@ -138,2 +138,6 @@ UglifyJS 3 | ||
--warn Print warning messages. | ||
--webkit Support non-standard Safari/Webkit. | ||
Equivalent to setting `webkit: true` in `minify()` | ||
for `mangle` and `output` options. | ||
By default UglifyJS will not try to be Safari-proof. | ||
--wrap <name> Embed everything in a big function, making the | ||
@@ -523,2 +527,5 @@ “exports” and “global” variables available. You | ||
- `webkit` (default `false`) -- enable workarounds for Safari/WebKit bugs. | ||
PhantomJS users should set this option to `true`. | ||
## Minify options structure | ||
@@ -873,2 +880,4 @@ | ||
- `galio` (default `false`) -- enable workarounds for ANT Galio bugs | ||
- `indent_level` (default `4`) | ||
@@ -912,4 +921,3 @@ | ||
- `webkit` (default `false`) -- enable workarounds for WebKit bugs. | ||
PhantomJS users should set this option to `true`. | ||
- `v8` (default `false`) -- enable workarounds for Chrome & Node.js bugs | ||
@@ -1145,3 +1153,3 @@ - `width` (default `80`) -- only takes effect when beautification is on, this | ||
#### Source maps and debugging | ||
### Source maps and debugging | ||
@@ -1158,2 +1166,6 @@ Various `compress` transforms that simplify, rearrange, inline and remove code | ||
- The code does not rely on preserving its runtime performance characteristics. | ||
Typically uglified code will run faster due to less instructions and easier | ||
inlining, but may be slower on rare occasions for a specific platform, e.g. | ||
see [`reduce_funcs`](#compress-options). | ||
- `.toString()` and `.valueOf()` don't have side effects, and for built-in | ||
@@ -1186,1 +1198,5 @@ objects they have not been overridden. | ||
``` | ||
- Use of `arguments` alongside destructuring as function parameters, e.g. | ||
`function({}, arguments) {}` will result in `SyntaxError` in earlier versions | ||
of Chrome and Node.js - UglifyJS may modify the input which in turn may | ||
suppress those errors. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
950521
24651
1196