diff --git a/bin/uglifyjs b/bin/uglifyjs index 2d03d99a..197e42bf 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -344,9 +344,9 @@ function run() { var list = annotations[node.start.file]; var pure = list[node.start.pos]; if (!pure) { - var pos = node.start.parens; - if (pos) for (var i = 0; !pure && i < pos.length; i++) { - pure = list[pos[i]]; + var tokens = node.start.parens; + if (tokens) for (var i = 0; !pure && i < tokens.length; i++) { + pure = list[tokens[i].pos]; } } if (pure) node.pure = pure; diff --git a/lib/ast.js b/lib/ast.js index 590c09bf..28e437f7 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -56,35 +56,31 @@ function DEFNODE(type, props, methods, base) { code.push("this.", prop, "=props.", prop, ";"); }); code.push("}"); - var proto = base && new base; - if (proto && proto.initialize || methods && methods.initialize) code.push("this.initialize();"); - code.push("}"); + var proto = Object.create(base && base.prototype); + if (methods.initialize || proto.initialize) code.push("this.initialize();"); + code.push("};"); var ctor = new Function(code.join(""))(); - if (proto) { - ctor.prototype = proto; - ctor.BASE = base; - } - if (base) base.SUBCLASSES.push(ctor); + ctor.prototype = proto; ctor.prototype.CTOR = ctor; - ctor.PROPS = props || null; - ctor.SELF_PROPS = self_props; - ctor.SUBCLASSES = []; - if (type) { - ctor.prototype.TYPE = ctor.TYPE = type; - } - if (methods) for (var name in methods) if (HOP(methods, name)) { - if (/^\$/.test(name)) { - ctor[name.substr(1)] = methods[name]; - } else { - ctor.prototype[name] = methods[name]; - } + ctor.prototype.TYPE = ctor.TYPE = type; + if (base) { + ctor.BASE = base; + base.SUBCLASSES.push(ctor); } ctor.DEFMETHOD = function(name, method) { this.prototype[name] = method; }; - if (typeof exports !== "undefined") { - exports["AST_" + type] = ctor; + ctor.PROPS = props; + ctor.SELF_PROPS = self_props; + ctor.SUBCLASSES = []; + for (var name in methods) if (HOP(methods, name)) { + if (/^\$/.test(name)) { + ctor[name.substr(1)] = methods[name]; + } else { + ctor.DEFMETHOD(name, methods[name]); + } } + if (typeof exports !== "undefined") exports["AST_" + type] = ctor; return ctor; } diff --git a/lib/compress.js b/lib/compress.js index a9671257..275d2980 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1510,7 +1510,7 @@ merge(Compressor.prototype, { function is_lhs_read_only(lhs, compressor) { if (lhs instanceof AST_ObjectIdentity) return true; if (lhs instanceof AST_PropAccess) { - if (lhs.property == "__proto__") return true; + if (lhs.property === "__proto__") return true; lhs = lhs.expression; if (lhs instanceof AST_SymbolRef) { if (lhs.is_immutable()) return false; @@ -3842,7 +3842,7 @@ merge(Compressor.prototype, { def(AST_Object, function(compressor, force) { return is_strict(compressor, force) && !all(this.properties, function(prop) { if (!(prop instanceof AST_ObjectKeyVal)) return false; - return !(prop.key == "__proto__" && prop.value._dot_throw(compressor, force)); + return !(prop.key === "__proto__" && prop.value._dot_throw(compressor, force)); }); }); def(AST_ObjectIdentity, function(compressor, force) { @@ -6727,7 +6727,7 @@ merge(Compressor.prototype, { return insert_statements(body, node, in_list); } if (node instanceof AST_Import) { - if (node.properties && node.properties == 0) node.properties = null; + if (node.properties && node.properties.length == 0) node.properties = null; return node; } if (node instanceof AST_Sequence) { @@ -11809,7 +11809,7 @@ merge(Compressor.prototype, { var props = expr.properties; for (var i = props.length; --i >= 0;) { var prop = props[i]; - if (prop.key != key) continue; + if (prop.key !== key) continue; if (!all(props, can_hoist_property)) break; if (!safe_to_flatten(prop.value, compressor)) break; props = props.map(function(prop) { diff --git a/lib/parse.js b/lib/parse.js index 463b2103..eb2dc01a 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -1334,21 +1334,19 @@ function parse($TEXT, options) { if (is("punc", "{")) { body = block_(); value = null; - if (S.input.has_directive("use strict")) { - argnames.forEach(strict_verify_symbol); - } } else { body = []; handle_regexp(); value = maybe_assign(); } + var is_strict = S.input.has_directive("use strict"); S.input.pop_directives_stack(); --S.in_function; S.in_loop = loop; S.labels = labels; S.in_generator = was_gen; S.in_async = was_async; - return new (async ? AST_AsyncArrow : AST_Arrow)({ + var node = new (async ? AST_AsyncArrow : AST_Arrow)({ start: start, argnames: argnames, rest: rest, @@ -1356,6 +1354,8 @@ function parse($TEXT, options) { value: value, end: prev(), }); + if (is_strict) node.each_argname(strict_verify_symbol); + return node; } var function_ = function(ctor) { @@ -1388,23 +1388,24 @@ function parse($TEXT, options) { S.in_loop = 0; S.labels = []; var body = block_(); - if (S.input.has_directive("use strict")) { - if (name) strict_verify_symbol(name); - argnames.forEach(strict_verify_symbol); - if (argnames.rest) strict_verify_symbol(argnames.rest); - } + var is_strict = S.input.has_directive("use strict"); S.input.pop_directives_stack(); --S.in_function; S.in_loop = loop; S.labels = labels; S.in_generator = was_gen; S.in_async = was_async; - return new ctor({ + var node = new ctor({ name: name, argnames: argnames, rest: argnames.rest || null, body: body }); + if (is_strict) { + if (name) strict_verify_symbol(name); + node.each_argname(strict_verify_symbol); + } + return node; }; function if_() { diff --git a/test/compress/imports.js b/test/compress/imports.js index d0e6af56..0accb3ec 100644 --- a/test/compress/imports.js +++ b/test/compress/imports.js @@ -94,13 +94,15 @@ drop_unused: { } input: { import a, * as b from "foo"; - import { c, bar as d } from "baz"; - console.log(c); + import { c } from "bar"; + import { d, _ as e } from "baz"; + console.log(d); } expect: { import "foo"; - import { c as c } from "baz"; - console.log(c); + import "bar"; + import { d as d } from "baz"; + console.log(d); } }