aboutsummaryrefslogtreecommitdiff
path: root/node_modules/uglify-js
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-05-24 15:10:37 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-05-24 15:11:17 +0200
commit7a3df06eb573d36142bd1a8e03c5ce8752d300b3 (patch)
tree70bfaea8884c374876f607774850a3a51c0cb381 /node_modules/uglify-js
parentaca1143cb9eed16cf37f04e475e4257418dd18ac (diff)
fix build issues and add typedoc
Diffstat (limited to 'node_modules/uglify-js')
-rw-r--r--node_modules/uglify-js/README.md48
-rwxr-xr-xnode_modules/uglify-js/bin/uglifyjs16
-rw-r--r--node_modules/uglify-js/lib/ast.js13
-rw-r--r--node_modules/uglify-js/lib/compress.js252
-rw-r--r--node_modules/uglify-js/lib/mozilla-ast.js52
-rw-r--r--node_modules/uglify-js/lib/output.js10
-rw-r--r--node_modules/uglify-js/lib/parse.js113
-rw-r--r--node_modules/uglify-js/lib/scope.js5
-rw-r--r--node_modules/uglify-js/package.json7
9 files changed, 316 insertions, 200 deletions
diff --git a/node_modules/uglify-js/README.md b/node_modules/uglify-js/README.md
index d15f114ce..8c1d67642 100644
--- a/node_modules/uglify-js/README.md
+++ b/node_modules/uglify-js/README.md
@@ -11,9 +11,10 @@ There's also an
Chrome and probably Safari).
#### Note:
-- release versions of `uglify-js` only support ECMAScript 5 (ES5). If you wish to minify
-ES2015+ (ES6+) code then please use the [harmony](#harmony) development branch.
-- Node 7 has a known performance regression and runs `uglify-js` twice as slow.
+- `uglify-js` only supports ECMAScript 5 (ES5).
+- Support for `const` is [present but incomplete](#support-for-const), and may not be
+ transformed properly.
+- Those wishing to minify ES2015+ (ES6+) should use the `npm` package [**uglify-es**](https://github.com/mishoo/UglifyJS2/tree/harmony).
Install
-------
@@ -29,12 +30,6 @@ From NPM for programmatic use:
npm install uglify-js
-From Git:
-
- git clone git://github.com/mishoo/UglifyJS2.git
- cd UglifyJS2
- npm link .
-
Usage
-----
@@ -358,6 +353,9 @@ to set `true`; it's effectively a shortcut for `foo=true`).
- `unsafe_proto` (default: false) -- optimize expressions like
`Array.prototype.slice.call(a)` into `[].slice.call(a)`
+- `unsafe_regexp` (default: false) -- enable substitutions of variables with
+ `RegExp` values the same way as if they are constants.
+
- `conditionals` -- apply optimizations for `if`-s and conditional
expressions
@@ -441,13 +439,19 @@ to set `true`; it's effectively a shortcut for `foo=true`).
compressor from discarding function names. Useful for code relying on
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle).
-- `passes` -- default `1`. Number of times to run compress. Use an
- integer argument larger than 1 to further reduce code size in some cases.
- Note: raising the number of passes will increase uglify compress time.
+- `passes` -- default `1`. Number of times to run compress with a maximum of 3.
+ In some cases more than one pass leads to further compressed code. Keep in
+ mind more passes will take more time.
- `keep_infinity` -- default `false`. Pass `true` to prevent `Infinity` from
being compressed into `1/0`, which may cause performance issues on Chrome.
+- `side_effects` -- default `true`. Pass `false` to disable potentially dropping
+ functions marked as "pure". A function call is marked as "pure" if a comment
+ annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
+ example: `/*@__PURE__*/foo();`
+
+
### The `unsafe` option
It enables some transformations that *might* break code logic in certain
@@ -983,19 +987,9 @@ The `source_map_options` (optional) can contain the following properties:
[compressor]: http://lisperator.net/uglifyjs/compress
[parser]: http://lisperator.net/uglifyjs/parser
-#### Harmony
-
-If you wish to use the experimental [harmony](https://github.com/mishoo/UglifyJS2/commits/harmony)
-branch to minify ES2015+ (ES6+) code please use the following in your `package.json` file:
-
-```
-"uglify-js": "git+https://github.com/mishoo/UglifyJS2.git#harmony"
-```
-
-or to directly install the experimental harmony version of uglify:
-
-```
-npm install --save-dev uglify-js@github:mishoo/UglifyJS2#harmony
-```
+#### Support for `const`
-See [#448](https://github.com/mishoo/UglifyJS2/issues/448) for additional details.
+`const` in `uglify-js@2.x` has function scope and as such behaves much like
+`var` - unlike `const` in ES2015 (ES6) which has block scope. It is recommended
+to avoid using `const` for this reason as it will have undefined behavior when
+run on an ES2015 compatible browser.
diff --git a/node_modules/uglify-js/bin/uglifyjs b/node_modules/uglify-js/bin/uglifyjs
index 635ca3651..63b2f26f1 100755
--- a/node_modules/uglify-js/bin/uglifyjs
+++ b/node_modules/uglify-js/bin/uglifyjs
@@ -367,19 +367,19 @@ var index = 0;
if (ex instanceof UglifyJS.JS_Parse_Error) {
print_error("Parse error at " + file + ":" + ex.line + "," + ex.col);
var col = ex.col;
- var line = code.split(/\r?\n/)[ex.line - (col ? 1 : 2)];
+ var lines = code.split(/\r?\n/);
+ var line = lines[ex.line - 1];
+ if (!line && !col) {
+ line = lines[ex.line - 2];
+ col = line.length;
+ }
if (line) {
if (col > 40) {
line = line.slice(col - 40);
col = 40;
}
- if (col) {
- print_error(line.slice(0, 80));
- print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
- } else {
- print_error(line.slice(-40));
- print_error(line.slice(-40).replace(/\S/g, " ") + "^");
- }
+ print_error(line.slice(0, 80));
+ print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
}
print_error(ex.stack);
process.exit(1);
diff --git a/node_modules/uglify-js/lib/ast.js b/node_modules/uglify-js/lib/ast.js
index ba1330f40..028772f3f 100644
--- a/node_modules/uglify-js/lib/ast.js
+++ b/node_modules/uglify-js/lib/ast.js
@@ -214,12 +214,13 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
clone: function(deep) {
var node = this._clone(deep);
if (deep) {
- var refs = node.label.references;
- var label = this.label;
+ var label = node.label;
+ var def = this.label;
node.walk(new TreeWalker(function(node) {
if (node instanceof AST_LoopControl
- && node.label && node.label.thedef === label) {
- refs.push(node);
+ && node.label && node.label.thedef === def) {
+ node.label.thedef = label;
+ label.references.push(node);
}
}));
}
@@ -797,8 +798,8 @@ var AST_Object = DEFNODE("Object", "properties", {
var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
$documentation: "Base class for literal object properties",
$propdoc: {
- key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an arbitrary AST_Node.",
- value: "[AST_Node] property value. For setters and getters this is an AST_Function."
+ key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an AST_SymbolAccessor.",
+ value: "[AST_Node] property value. For setters and getters this is an AST_Accessor."
},
_walk: function(visitor) {
return visitor._visit(this, function(){
diff --git a/node_modules/uglify-js/lib/compress.js b/node_modules/uglify-js/lib/compress.js
index 1d9258cf6..d8a491ebc 100644
--- a/node_modules/uglify-js/lib/compress.js
+++ b/node_modules/uglify-js/lib/compress.js
@@ -84,6 +84,7 @@ function Compressor(options, false_by_default) {
unsafe_comps : false,
unsafe_math : false,
unsafe_proto : false,
+ unsafe_regexp : false,
unused : !false_by_default,
warnings : true,
}, true);
@@ -271,6 +272,14 @@ merge(Compressor.prototype, {
if (d.fixed === undefined || !is_safe(d)
|| is_modified(node, 0, node.fixed_value() instanceof AST_Lambda)) {
d.fixed = false;
+ } else {
+ var parent = tw.parent();
+ if (parent instanceof AST_Assign && parent.operator == "=" && node === parent.right
+ || parent instanceof AST_Call && node !== parent.expression
+ || parent instanceof AST_Return && node === parent.value && node.scope !== d.scope
+ || parent instanceof AST_VarDef && node === parent.value) {
+ d.escaped = true;
+ }
}
}
if (node instanceof AST_SymbolCatch) {
@@ -308,21 +317,55 @@ merge(Compressor.prototype, {
safe_ids = save_ids;
return true;
}
- var iife;
- if (node instanceof AST_Function
- && !node.name
- && (iife = tw.parent()) instanceof AST_Call
- && iife.expression === node) {
- // Virtually turn IIFE parameters into variable definitions:
- // (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})()
- // So existing transformation rules can work on them.
- node.argnames.forEach(function(arg, i) {
- var d = arg.definition();
- d.fixed = function() {
- return iife.args[i] || make_node(AST_Undefined, iife);
- };
- mark(d, true);
- });
+ if (node instanceof AST_Function) {
+ push();
+ var iife;
+ if (!node.name
+ && (iife = tw.parent()) instanceof AST_Call
+ && iife.expression === node) {
+ // Virtually turn IIFE parameters into variable definitions:
+ // (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})()
+ // So existing transformation rules can work on them.
+ node.argnames.forEach(function(arg, i) {
+ var d = arg.definition();
+ if (!node.uses_arguments && d.fixed === undefined) {
+ d.fixed = function() {
+ return iife.args[i] || make_node(AST_Undefined, iife);
+ };
+ mark(d, true);
+ } else {
+ d.fixed = false;
+ }
+ });
+ }
+ descend();
+ pop();
+ return true;
+ }
+ if (node instanceof AST_Accessor) {
+ var save_ids = safe_ids;
+ safe_ids = Object.create(null);
+ descend();
+ safe_ids = save_ids;
+ return true;
+ }
+ if (node instanceof AST_Binary
+ && (node.operator == "&&" || node.operator == "||")) {
+ node.left.walk(tw);
+ push();
+ node.right.walk(tw);
+ pop();
+ return true;
+ }
+ if (node instanceof AST_Conditional) {
+ node.condition.walk(tw);
+ push();
+ node.consequent.walk(tw);
+ pop();
+ push();
+ node.alternative.walk(tw);
+ pop();
+ return true;
}
if (node instanceof AST_If || node instanceof AST_DWLoop) {
node.condition.walk(tw);
@@ -359,7 +402,19 @@ merge(Compressor.prototype, {
pop();
return true;
}
- if (node instanceof AST_Catch || node instanceof AST_SwitchBranch) {
+ if (node instanceof AST_Try) {
+ push();
+ walk_body(node, tw);
+ pop();
+ if (node.bcatch) {
+ push();
+ node.bcatch.walk(tw);
+ pop();
+ }
+ if (node.bfinally) node.bfinally.walk(tw);
+ return true;
+ }
+ if (node instanceof AST_SwitchBranch) {
push();
descend();
pop();
@@ -393,7 +448,10 @@ merge(Compressor.prototype, {
}
function reset_def(def) {
- if (toplevel || !def.global || def.orig[0] instanceof AST_SymbolConst) {
+ def.escaped = false;
+ if (def.scope.uses_eval) {
+ def.fixed = false;
+ } else if (toplevel || !def.global || def.orig[0] instanceof AST_SymbolConst) {
def.fixed = undefined;
} else {
def.fixed = false;
@@ -419,6 +477,14 @@ merge(Compressor.prototype, {
return fixed();
});
+ function is_reference_const(ref) {
+ if (!(ref instanceof AST_SymbolRef)) return false;
+ var orig = ref.definition().orig;
+ for (var i = orig.length; --i >= 0;) {
+ if (orig[i] instanceof AST_SymbolConst) return true;
+ }
+ }
+
function find_variable(compressor, name) {
var scope, i = 0;
while (scope = compressor.parent(i++)) {
@@ -1160,12 +1226,12 @@ merge(Compressor.prototype, {
&& !node.expression.has_side_effects(compressor);
}
- // may_eq_null()
- // returns true if this node may evaluate to null or undefined
+ // may_throw_on_access()
+ // returns true if this node may be null, undefined or contain `AST_Accessor`
(function(def) {
- AST_Node.DEFMETHOD("may_eq_null", function(compressor) {
+ AST_Node.DEFMETHOD("may_throw_on_access", function(compressor) {
var pure_getters = compressor.option("pure_getters");
- return !pure_getters || this._eq_null(pure_getters);
+ return !pure_getters || this._throw_on_access(pure_getters);
});
function is_strict(pure_getters) {
@@ -1177,7 +1243,12 @@ merge(Compressor.prototype, {
def(AST_Undefined, return_true);
def(AST_Constant, return_false);
def(AST_Array, return_false);
- def(AST_Object, return_false);
+ def(AST_Object, function(pure_getters) {
+ if (!is_strict(pure_getters)) return false;
+ for (var i = this.properties.length; --i >=0;)
+ if (this.properties[i].value instanceof AST_Accessor) return true;
+ return false;
+ });
def(AST_Function, return_false);
def(AST_UnaryPostfix, return_false);
def(AST_UnaryPrefix, function() {
@@ -1186,33 +1257,33 @@ merge(Compressor.prototype, {
def(AST_Binary, function(pure_getters) {
switch (this.operator) {
case "&&":
- return this.left._eq_null(pure_getters);
+ return this.left._throw_on_access(pure_getters);
case "||":
- return this.left._eq_null(pure_getters)
- && this.right._eq_null(pure_getters);
+ return this.left._throw_on_access(pure_getters)
+ && this.right._throw_on_access(pure_getters);
default:
return false;
}
})
def(AST_Assign, function(pure_getters) {
return this.operator == "="
- && this.right._eq_null(pure_getters);
+ && this.right._throw_on_access(pure_getters);
})
def(AST_Conditional, function(pure_getters) {
- return this.consequent._eq_null(pure_getters)
- || this.alternative._eq_null(pure_getters);
+ return this.consequent._throw_on_access(pure_getters)
+ || this.alternative._throw_on_access(pure_getters);
})
def(AST_Seq, function(pure_getters) {
- return this.cdr._eq_null(pure_getters);
+ return this.cdr._throw_on_access(pure_getters);
});
def(AST_SymbolRef, function(pure_getters) {
if (this.is_undefined) return true;
if (!is_strict(pure_getters)) return false;
var fixed = this.fixed_value();
- return !fixed || fixed._eq_null(pure_getters);
+ return !fixed || fixed._throw_on_access(pure_getters);
});
})(function(node, func) {
- node.DEFMETHOD("_eq_null", func);
+ node.DEFMETHOD("_throw_on_access", func);
});
/* -----[ boolean/negation helpers ]----- */
@@ -1549,23 +1620,20 @@ merge(Compressor.prototype, {
: ev(this.alternative, compressor);
});
def(AST_SymbolRef, function(compressor){
- if (this._evaluating) throw def;
+ if (!compressor.option("reduce_vars") || this._evaluating) throw def;
this._evaluating = true;
try {
var fixed = this.fixed_value();
- if (compressor.option("reduce_vars") && fixed) {
- if (compressor.option("unsafe")) {
- if (!HOP(fixed, "_evaluated")) {
- fixed._evaluated = ev(fixed, compressor);
- }
- return fixed._evaluated;
- }
- return ev(fixed, compressor);
- }
+ if (!fixed) throw def;
+ var value = ev(fixed, compressor);
+ if (!HOP(fixed, "_eval")) fixed._eval = function() {
+ return value;
+ };
+ if (value && typeof value == "object" && this.definition().escaped) throw def;
+ return value;
} finally {
this._evaluating = false;
}
- throw def;
});
def(AST_PropAccess, function(compressor){
if (compressor.option("unsafe")) {
@@ -1755,11 +1823,11 @@ merge(Compressor.prototype, {
return any(this.elements, compressor);
});
def(AST_Dot, function(compressor){
- return this.expression.may_eq_null(compressor)
+ return this.expression.may_throw_on_access(compressor)
|| this.expression.has_side_effects(compressor);
});
def(AST_Sub, function(compressor){
- return this.expression.may_eq_null(compressor)
+ return this.expression.may_throw_on_access(compressor)
|| this.expression.has_side_effects(compressor)
|| this.property.has_side_effects(compressor);
});
@@ -1891,6 +1959,7 @@ merge(Compressor.prototype, {
&& node instanceof AST_Assign
&& node.operator == "="
&& node.left instanceof AST_SymbolRef
+ && !is_reference_const(node.left)
&& scope === self) {
node.right.walk(tw);
return true;
@@ -1980,7 +2049,7 @@ merge(Compressor.prototype, {
}
return node;
}
- if (drop_vars && node instanceof AST_Definitions && !(tt.parent() instanceof AST_ForIn)) {
+ if (drop_vars && node instanceof AST_Definitions && !(tt.parent() instanceof AST_ForIn && tt.parent().init === node)) {
var def = node.definitions.filter(function(def){
if (def.value) def.value = def.value.transform(tt);
var sym = def.name.definition();
@@ -2058,26 +2127,32 @@ merge(Compressor.prototype, {
return maintain_this_binding(tt.parent(), node, node.right.transform(tt));
}
}
+ // certain combination of unused name + side effect leads to:
+ // https://github.com/mishoo/UglifyJS2/issues/44
+ // https://github.com/mishoo/UglifyJS2/issues/1830
+ // that's an invalid AST.
+ // We fix it at this stage by moving the `var` outside the `for`.
if (node instanceof AST_For) {
descend(node, this);
-
if (node.init instanceof AST_BlockStatement) {
- // certain combination of unused name + side effect leads to:
- // https://github.com/mishoo/UglifyJS2/issues/44
- // that's an invalid AST.
- // We fix it at this stage by moving the `var` outside the `for`.
-
- var body = node.init.body.slice(0, -1);
- node.init = node.init.body.slice(-1)[0].body;
- body.push(node);
-
- return in_list ? MAP.splice(body) : make_node(AST_BlockStatement, node, {
- body: body
- });
+ var block = node.init;
+ node.init = block.body.pop();
+ block.body.push(node);
+ return in_list ? MAP.splice(block.body) : block;
} else if (is_empty(node.init)) {
node.init = null;
- return node;
}
+ return node;
+ }
+ if (node instanceof AST_LabeledStatement && node.body instanceof AST_For) {
+ descend(node, this);
+ if (node.body instanceof AST_BlockStatement) {
+ var block = node.body;
+ node.body = block.body.pop();
+ block.body.push(node);
+ return in_list ? MAP.splice(block.body) : block;
+ }
+ return node;
}
if (node instanceof AST_Scope && node !== self)
return node;
@@ -2256,6 +2331,7 @@ merge(Compressor.prototype, {
var args = trim(this.args, compressor, first_in_statement);
return args && AST_Seq.from_array(args);
});
+ def(AST_Accessor, return_null);
def(AST_Function, return_null);
def(AST_Binary, function(compressor, first_in_statement){
var right = this.right.drop_side_effect_free(compressor);
@@ -2326,11 +2402,11 @@ merge(Compressor.prototype, {
return values && AST_Seq.from_array(values);
});
def(AST_Dot, function(compressor, first_in_statement){
- if (this.expression.may_eq_null(compressor)) return this;
+ if (this.expression.may_throw_on_access(compressor)) return this;
return this.expression.drop_side_effect_free(compressor, first_in_statement);
});
def(AST_Sub, function(compressor, first_in_statement){
- if (this.expression.may_eq_null(compressor)) return this;
+ if (this.expression.may_throw_on_access(compressor)) return this;
var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
if (!expression) return this.property.drop_side_effect_free(compressor, first_in_statement);
var property = this.property.drop_side_effect_free(compressor);
@@ -2380,7 +2456,7 @@ merge(Compressor.prototype, {
if (compressor.option("dead_code") && self instanceof AST_While) {
var a = [];
extract_declarations_from_unreachable_code(compressor, self.body, a);
- return make_node(AST_BlockStatement, self, { body: a });
+ return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
}
if (self instanceof AST_Do) {
var has_loop_control = false;
@@ -2389,7 +2465,8 @@ merge(Compressor.prototype, {
if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === self)
return has_loop_control = true;
});
- self.walk(tw);
+ var parent = compressor.parent();
+ (parent instanceof AST_LabeledStatement ? parent : self).walk(tw);
if (!has_loop_control) return self.body;
}
}
@@ -2459,7 +2536,7 @@ merge(Compressor.prototype, {
}));
}
extract_declarations_from_unreachable_code(compressor, self.body, a);
- return make_node(AST_BlockStatement, self, { body: a });
+ return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
}
if (cond !== self.condition) {
cond = make_node_from_constant(cond, self.condition).transform(compressor);
@@ -2711,9 +2788,9 @@ merge(Compressor.prototype, {
var body = [];
if (self.bcatch) extract_declarations_from_unreachable_code(compressor, self.bcatch, body);
if (self.bfinally) body = body.concat(self.bfinally.body);
- return body.length > 0 ? make_node(AST_BlockStatement, self, {
+ return make_node(AST_BlockStatement, self, {
body: body
- }).optimize(compressor) : make_node(AST_EmptyStatement, self);
+ }).optimize(compressor);
}
return self;
});
@@ -3041,7 +3118,8 @@ merge(Compressor.prototype, {
}
if (left
&& !(left instanceof AST_SymbolRef
- && left.definition().orig[0] instanceof AST_SymbolLambda)) {
+ && (left.definition().orig[0] instanceof AST_SymbolLambda
+ || is_reference_const(left)))) {
var parent, field;
var cdr = self.cdr;
while (true) {
@@ -3595,29 +3673,55 @@ merge(Compressor.prototype, {
return make_node(AST_Infinity, self).optimize(compressor);
}
}
- if (compressor.option("evaluate") && compressor.option("reduce_vars")) {
+ if (compressor.option("evaluate")
+ && compressor.option("reduce_vars")
+ && is_lhs(self, compressor.parent()) !== self) {
var d = self.definition();
var fixed = self.fixed_value();
if (fixed) {
if (d.should_replace === undefined) {
var init = fixed.evaluate(compressor);
- if (init !== fixed) {
+ if (init !== fixed && (compressor.option("unsafe_regexp") || !(init instanceof RegExp))) {
init = make_node_from_constant(init, fixed);
- var value = best_of_expression(init.optimize(compressor), fixed).print_to_string().length;
+ var value = init.optimize(compressor).print_to_string().length;
+ var fn;
+ if (has_symbol_ref(fixed)) {
+ fn = function() {
+ var result = init.optimize(compressor);
+ return result === init ? result.clone(true) : result;
+ };
+ } else {
+ value = Math.min(value, fixed.print_to_string().length);
+ fn = function() {
+ var result = best_of_expression(init.optimize(compressor), fixed);
+ return result === init || result === fixed ? result.clone(true) : result;
+ };
+ }
var name = d.name.length;
- var freq = d.references.length;
- var overhead = d.global || !freq ? 0 : (name + 2 + value) / freq;
- d.should_replace = value <= name + overhead ? init : false;
+ var overhead = 0;
+ if (compressor.option("unused") && (!d.global || compressor.option("toplevel"))) {
+ overhead = (name + 2 + value) / d.references.length;
+ }
+ d.should_replace = value <= name + overhead ? fn : false;
} else {
d.should_replace = false;
}
}
if (d.should_replace) {
- return best_of_expression(d.should_replace.optimize(compressor), fixed).clone(true);
+ return d.should_replace();
}
}
}
return self;
+
+ function has_symbol_ref(value) {
+ var found;
+ value.walk(new TreeWalker(function(node) {
+ if (node instanceof AST_SymbolRef) found = true;
+ if (found) return true;
+ }));
+ return found;
+ }
});
function is_atomic(lhs, self) {
diff --git a/node_modules/uglify-js/lib/mozilla-ast.js b/node_modules/uglify-js/lib/mozilla-ast.js
index 12b55dc5b..88a2eb59f 100644
--- a/node_modules/uglify-js/lib/mozilla-ast.js
+++ b/node_modules/uglify-js/lib/mozilla-ast.js
@@ -111,23 +111,19 @@
},
Property: function(M) {
var key = M.key;
- var name = key.type == "Identifier" ? key.name : key.value;
var args = {
start : my_start_token(key),
end : my_end_token(M.value),
- key : name,
+ key : key.type == "Identifier" ? key.name : key.value,
value : from_moz(M.value)
};
- switch (M.kind) {
- case "init":
- return new AST_ObjectKeyVal(args);
- case "set":
- args.value.name = from_moz(key);
- return new AST_ObjectSetter(args);
- case "get":
- args.value.name = from_moz(key);
- return new AST_ObjectGetter(args);
- }
+ if (M.kind == "init") return new AST_ObjectKeyVal(args);
+ args.key = new AST_SymbolAccessor({
+ name: args.key
+ });
+ args.value = new AST_Accessor(args.value);
+ if (M.kind == "get") return new AST_ObjectGetter(args);
+ if (M.kind == "set") return new AST_ObjectSetter(args);
},
ArrayExpression: function(M) {
return new AST_Array({
@@ -256,10 +252,7 @@
map("CallExpression", AST_Call, "callee>expression, arguments@args");
def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
- return {
- type: "Program",
- body: M.body.map(to_moz)
- };
+ return to_moz_scope("Program", M);
});
def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) {
@@ -267,7 +260,7 @@
type: "FunctionDeclaration",
id: to_moz(M.name),
params: M.argnames.map(to_moz),
- body: to_moz_block(M)
+ body: to_moz_scope("BlockStatement", M)
}
});
@@ -276,7 +269,7 @@
type: "FunctionExpression",
id: to_moz(M.name),
params: M.argnames.map(to_moz),
- body: to_moz_block(M)
+ body: to_moz_scope("BlockStatement", M)
}
});
@@ -382,11 +375,10 @@
});
def_to_moz(AST_ObjectProperty, function To_Moz_Property(M) {
- var key = (
- is_identifier(M.key)
- ? {type: "Identifier", name: M.key}
- : {type: "Literal", value: M.key}
- );
+ var key = {
+ type: "Literal",
+ value: M.key instanceof AST_SymbolAccessor ? M.key.name : M.key
+ };
var kind;
if (M instanceof AST_ObjectKeyVal) {
kind = "init";
@@ -547,8 +539,8 @@
moz_to_me = new Function("U2", "my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")(
exports, my_start_token, my_end_token, from_moz
);
- me_to_moz = new Function("to_moz", "to_moz_block", "return(" + me_to_moz + ")")(
- to_moz, to_moz_block
+ me_to_moz = new Function("to_moz", "to_moz_block", "to_moz_scope", "return(" + me_to_moz + ")")(
+ to_moz, to_moz_block, to_moz_scope
);
MOZ_TO_ME[moztype] = moz_to_me;
def_to_moz(mytype, me_to_moz);
@@ -606,4 +598,14 @@
};
};
+ function to_moz_scope(type, node) {
+ var body = node.body.map(to_moz);
+ if (node.body[0] instanceof AST_SimpleStatement && node.body[0].body instanceof AST_String) {
+ body.unshift(to_moz(new AST_EmptyStatement(node.body[0])));
+ }
+ return {
+ type: type,
+ body: body
+ };
+ };
})();
diff --git a/node_modules/uglify-js/lib/output.js b/node_modules/uglify-js/lib/output.js
index 9ac50c08a..0731fb492 100644
--- a/node_modules/uglify-js/lib/output.js
+++ b/node_modules/uglify-js/lib/output.js
@@ -190,11 +190,7 @@ function OutputStream(options) {
var might_need_space = false;
var might_need_semicolon = false;
var might_add_newline = 0;
- var last = null;
-
- function last_char() {
- return last.charAt(last.length - 1);
- };
+ var last = "";
var ensure_line_len = options.max_line_len ? function() {
if (current_col > options.max_line_len) {
@@ -218,10 +214,11 @@ function OutputStream(options) {
function print(str) {
str = String(str);
var ch = str.charAt(0);
+ var prev = last.charAt(last.length - 1);
if (might_need_semicolon) {
might_need_semicolon = false;
- if ((!ch || ";}".indexOf(ch) < 0) && !/[;]$/.test(last)) {
+ if (prev == ":" && ch == "}" || (!ch || ";}".indexOf(ch) < 0) && prev != ";") {
if (options.semicolons || requireSemicolonChars(ch)) {
OUTPUT += ";";
current_col++;
@@ -258,7 +255,6 @@ function OutputStream(options) {
}
if (might_need_space) {
- var prev = last_char();
if ((is_identifier_char(prev)
&& (is_identifier_char(ch) || ch == "\\"))
|| (ch == "/" && ch == prev)
diff --git a/node_modules/uglify-js/lib/parse.js b/node_modules/uglify-js/lib/parse.js
index c34e13db6..014822ad9 100644
--- a/node_modules/uglify-js/lib/parse.js
+++ b/node_modules/uglify-js/lib/parse.js
@@ -111,7 +111,7 @@ var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u20
var NEWLINE_CHARS = makePredicate(characters("\n\r\u2028\u2029"));
-var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,.;:"));
+var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:"));
var PUNC_CHARS = makePredicate(characters("[]{}(),;:"));
@@ -285,7 +285,11 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX(value)) ||
(type == "keyword" && KEYWORDS_BEFORE_EXPRESSION(value)) ||
(type == "punc" && PUNC_BEFORE_EXPRESSION(value)));
- prev_was_dot = (type == "punc" && value == ".");
+ if (type == "punc" && value == ".") {
+ prev_was_dot = true;
+ } else if (!is_comment) {
+ prev_was_dot = false;
+ }
var ret = {
type : type,
value : value,
@@ -803,28 +807,23 @@ function parse($TEXT, options) {
};
var statement = embed_tokens(function() {
- var tmp;
handle_regexp();
switch (S.token.type) {
case "string":
- var dir = false;
- if (S.in_directives === true) {
- if ((is_token(peek(), "punc", ";") || peek().nlb) && S.token.raw.indexOf("\\") === -1) {
+ if (S.in_directives) {
+ var token = peek();
+ if (S.token.raw.indexOf("\\") == -1
+ && (token.nlb
+ || is_token(token, "eof")
+ || is_token(token, "punc", ";")
+ || is_token(token, "punc", "}"))) {
S.input.add_directive(S.token.value);
} else {
S.in_directives = false;
}
}
var dir = S.in_directives, stat = simple_statement();
- if (dir) {
- return new AST_Directive({
- start : stat.body.start,
- end : stat.body.end,
- quote : stat.body.quote,
- value : stat.body.value,
- });
- }
- return stat;
+ return dir ? new AST_Directive(stat.body) : stat;
case "num":
case "regexp":
case "operator":
@@ -856,75 +855,103 @@ function parse($TEXT, options) {
}
case "keyword":
- switch (tmp = S.token.value, next(), tmp) {
+ switch (S.token.value) {
case "break":
+ next();
return break_cont(AST_Break);
case "continue":
+ next();
return break_cont(AST_Continue);
case "debugger":
+ next();
semicolon();
return new AST_Debugger();
case "do":
+ next();
+ var body = in_loop(statement);
+ expect_token("keyword", "while");
+ var condition = parenthesised();
+ semicolon(true);
return new AST_Do({
- body : in_loop(statement),
- condition : (expect_token("keyword", "while"), tmp = parenthesised(), semicolon(true), tmp)
+ body : body,
+ condition : condition
});
case "while":
+ next();
return new AST_While({
condition : parenthesised(),
body : in_loop(statement)
});
case "for":
+ next();
return for_();
case "function":
+ next();
return function_(AST_Defun);
case "if":
+ next();
return if_();
case "return":
if (S.in_function == 0 && !options.bare_returns)
croak("'return' outside of function");
+ next();
+ var value = null;
+ if (is("punc", ";")) {
+ next();
+ } else if (!can_insert_semicolon()) {
+ value = expression(true);
+ semicolon();
+ }
return new AST_Return({
- value: ( is("punc", ";")
- ? (next(), null)
- : can_insert_semicolon()
- ? null
- : (tmp = expression(true), semicolon(), tmp) )
+ value: value
});
case "switch":
+ next();
return new AST_Switch({
expression : parenthesised(),
body : in_loop(switch_body_)
});
case "throw":
+ next();
if (S.token.nlb)
croak("Illegal newline after 'throw'");
+ var value = expression(true);
+ semicolon();
return new AST_Throw({
- value: (tmp = expression(true), semicolon(), tmp)
+ value: value
});
case "try":
+ next();
return try_();
case "var":
- return tmp = var_(), semicolon(), tmp;
+ next();
+ var node = var_();
+ semicolon();
+ return node;
case "const":
- return tmp = const_(), semicolon(), tmp;
+ next();
+ var node = const_();
+ semicolon();
+ return node;
case "with":
if (S.input.has_directive("use strict")) {
croak("Strict mode may not include a with statement");
}
+ next();
return new AST_With({
expression : parenthesised(),
body : statement()
@@ -1320,10 +1347,15 @@ function parse($TEXT, options) {
var type = start.type;
var name = as_property_name();
if (type == "name" && !is("punc", ":")) {
+ var key = new AST_SymbolAccessor({
+ start: S.token,
+ name: as_property_name(),
+ end: prev()
+ });
if (name == "get") {
a.push(new AST_ObjectGetter({
start : start,
- key : as_atom_node(),
+ key : key,
value : create_accessor(),
end : prev()
}));
@@ -1332,7 +1364,7 @@ function parse($TEXT, options) {
if (name == "set") {
a.push(new AST_ObjectSetter({
start : start,
- key : as_atom_node(),
+ key : key,
value : create_accessor(),
end : prev()
}));
@@ -1354,14 +1386,15 @@ function parse($TEXT, options) {
function as_property_name() {
var tmp = S.token;
- next();
switch (tmp.type) {
+ case "operator":
+ if (!KEYWORDS(tmp.value)) unexpected();
case "num":
case "string":
case "name":
- case "operator":
case "keyword":
case "atom":
+ next();
return tmp.value;
default:
unexpected();
@@ -1370,16 +1403,9 @@ function parse($TEXT, options) {
function as_name() {
var tmp = S.token;
+ if (tmp.type != "name") unexpected();
next();
- switch (tmp.type) {
- case "name":
- case "operator":
- case "keyword":
- case "atom":
- return tmp.value;
- default:
- unexpected();
- }
+ return tmp.value;
};
function _make_symbol(type) {
@@ -1440,14 +1466,14 @@ function parse($TEXT, options) {
if (is("operator") && UNARY_PREFIX(start.value)) {
next();
handle_regexp();
- var ex = make_unary(AST_UnaryPrefix, start.value, maybe_unary(allow_calls));
+ var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
ex.start = start;
ex.end = prev();
return ex;
}
var val = expr_atom(allow_calls);
while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) {
- val = make_unary(AST_UnaryPostfix, S.token.value, val);
+ val = make_unary(AST_UnaryPostfix, S.token, val);
val.start = start;
val.end = S.token;
next();
@@ -1455,9 +1481,10 @@ function parse($TEXT, options) {
return val;
};
- function make_unary(ctor, op, expr) {
+ function make_unary(ctor, token, expr) {
+ var op = token.value;
if ((op == "++" || op == "--") && !is_assignable(expr))
- croak("Invalid use of " + op + " operator", null, ctor === AST_UnaryPrefix ? expr.start.col - 1 : null);
+ croak("Invalid use of " + op + " operator", token.line, token.col, token.pos);
return new ctor({ operator: op, expression: expr });
};
diff --git a/node_modules/uglify-js/lib/scope.js b/node_modules/uglify-js/lib/scope.js
index 74760e4f4..bf6dbcbbf 100644
--- a/node_modules/uglify-js/lib/scope.js
+++ b/node_modules/uglify-js/lib/scope.js
@@ -361,11 +361,6 @@ AST_Symbol.DEFMETHOD("unmangleable", function(options){
return this.definition().unmangleable(options);
});
-// property accessors are not mangleable
-AST_SymbolAccessor.DEFMETHOD("unmangleable", function(){
- return true;
-});
-
// labels are always mangleable
AST_Label.DEFMETHOD("unmangleable", function(){
return false;
diff --git a/node_modules/uglify-js/package.json b/node_modules/uglify-js/package.json
index cfa8eb742..a06c051f3 100644
--- a/node_modules/uglify-js/package.json
+++ b/node_modules/uglify-js/package.json
@@ -4,7 +4,7 @@
"homepage": "http://lisperator.net/uglifyjs",
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
"license": "BSD-2-Clause",
- "version": "2.8.22",
+ "version": "2.8.27",
"engines": {
"node": ">=0.8.0"
},
@@ -33,10 +33,7 @@
"yargs": "~3.10.0"
},
"devDependencies": {
- "acorn": "~0.6.0",
- "escodegen": "~1.3.3",
- "esfuzz": "~0.3.1",
- "estraverse": "~1.5.1",
+ "acorn": "~5.0.3",
"mocha": "~2.3.4"
},
"optionalDependencies": {