diff options
author | Florian Dold <florian.dold@gmail.com> | 2017-05-24 15:10:37 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2017-05-24 15:11:17 +0200 |
commit | 7a3df06eb573d36142bd1a8e03c5ce8752d300b3 (patch) | |
tree | 70bfaea8884c374876f607774850a3a51c0cb381 /node_modules/uglify-js/lib | |
parent | aca1143cb9eed16cf37f04e475e4257418dd18ac (diff) |
fix build issues and add typedoc
Diffstat (limited to 'node_modules/uglify-js/lib')
-rw-r--r-- | node_modules/uglify-js/lib/ast.js | 13 | ||||
-rw-r--r-- | node_modules/uglify-js/lib/compress.js | 252 | ||||
-rw-r--r-- | node_modules/uglify-js/lib/mozilla-ast.js | 52 | ||||
-rw-r--r-- | node_modules/uglify-js/lib/output.js | 10 | ||||
-rw-r--r-- | node_modules/uglify-js/lib/parse.js | 113 | ||||
-rw-r--r-- | node_modules/uglify-js/lib/scope.js | 5 |
6 files changed, 285 insertions, 160 deletions
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; |