From a04da94b98f2f3f8f835397a202904bc0d545b67 Mon Sep 17 00:00:00 2001 From: jaywcjlove <398188662@qq.com> Date: Wed, 17 Jul 2024 22:56:52 +0800 Subject: [PATCH] released v3.19.0 --- lib/uglifyjs.js | 313 ++++++++++++++++++++++++++++++++++-------------- package.json | 2 +- 2 files changed, 222 insertions(+), 93 deletions(-) diff --git a/lib/uglifyjs.js b/lib/uglifyjs.js index 5835b07..a507ffd 100644 --- a/lib/uglifyjs.js +++ b/lib/uglifyjs.js @@ -471,8 +471,6 @@ DEF_BITPROPS(AST_Node, [ "private", // AST_Call "pure", - // AST_Assign - "redundant", // AST_Node "single_use", // AST_ClassProperty @@ -1269,9 +1267,12 @@ var AST_ClassProperty = DEFNODE("ClassProperty", "key private static value", { if (this.key != null) throw new Error("key must be null"); } else if (typeof this.key != "string") { if (!(this.key instanceof AST_Node)) throw new Error("key must be string or AST_Node"); + if (this.private) throw new Error("computed key cannot be private"); must_be_expression(this, "key"); + } else if (this.private) { + if (!/^#/.test(this.key)) throw new Error("private key must prefix with #"); } - if(this.value != null) { + if (this.value != null) { if (!(this.value instanceof AST_Node)) throw new Error("value must be AST_Node"); } }, @@ -1280,7 +1281,7 @@ var AST_ClassProperty = DEFNODE("ClassProperty", "key private static value", { var AST_ClassField = DEFNODE("ClassField", null, { $documentation: "A `class` field", _validate: function() { - if(this.value != null) must_be_expression(this, "value"); + if (this.value != null) must_be_expression(this, "value"); }, }, AST_ClassProperty); @@ -6573,7 +6574,7 @@ function Compressor(options, false_by_default) { }; } -Compressor.prototype = new TreeTransformer(function(node, descend, in_list) { +Compressor.prototype = new TreeTransformer(function(node, descend) { if (node._squeezed) return node; var is_scope = node instanceof AST_Scope; if (is_scope) { @@ -6658,7 +6659,7 @@ Compressor.prototype.compress = function(node) { }; (function(OPT) { - OPT(AST_Node, function(self, compressor) { + OPT(AST_Node, function(self) { return self; }); @@ -7026,15 +7027,38 @@ Compressor.prototype.compress = function(node) { } function push(tw, sequential) { + var defined_ids = Object.create(tw.defined_ids); var safe_ids = Object.create(tw.safe_ids); - if (!sequential) safe_ids.seq = {}; + if (!sequential) { + defined_ids.seq = {}; + safe_ids.seq = {}; + } + tw.defined_ids = defined_ids; tw.safe_ids = safe_ids; } function pop(tw) { + tw.defined_ids = Object.getPrototypeOf(tw.defined_ids); tw.safe_ids = Object.getPrototypeOf(tw.safe_ids); } + function access(tw, def) { + tw.defined_ids[def.id] = tw.defined_ids.seq; + } + + function assign(tw, def) { + tw.assigned_ids[def.id] = tw.defined_ids.seq; + tw.defined_ids[def.id] = false; + } + + function safe_to_access(tw, def) { + var seq = tw.defined_ids.seq; + var defined = tw.defined_ids[def.id]; + if (defined !== seq) return false; + var assigned = tw.assigned_ids[def.id]; + return !assigned || assigned === seq; + } + function mark(tw, def) { tw.safe_ids[def.id] = {}; } @@ -7327,9 +7351,13 @@ Compressor.prototype.compress = function(node) { return fixed_node; }, visit); walk_lambda(fn, tw); + var defined_ids = tw.defined_ids; var safe_ids = tw.safe_ids; pop_scope(tw, fn); - if (!aborts) tw.safe_ids = safe_ids; + if (!aborts) { + tw.defined_ids = defined_ids; + tw.safe_ids = safe_ids; + } return true; function visit(node, fixed) { @@ -7357,7 +7385,6 @@ Compressor.prototype.compress = function(node) { if (left.equals(right) && !left.has_side_effects(compressor)) { right.walk(tw); walk_prop(left); - node.redundant = true; return true; } if (ld && right instanceof AST_LambdaExpression) { @@ -7383,6 +7410,7 @@ Compressor.prototype.compress = function(node) { mark_assignment_to_arguments(left); return walk_lazy(); } + assign(tw, ld); ld.assignments++; var fixed = ld.fixed; if (is_modified(compressor, tw, node, node, 0)) { @@ -7451,6 +7479,7 @@ Compressor.prototype.compress = function(node) { return; } var d = sym.definition(); + assign(tw, d); d.assignments++; if (!fixed || sym.in_arg || !safe_to_assign(tw, d)) { walk(); @@ -7491,7 +7520,7 @@ Compressor.prototype.compress = function(node) { def(AST_BlockScope, function(tw, descend, compressor) { reset_block_variables(tw, compressor, this); }); - def(AST_Call, function(tw, descend) { + def(AST_Call, function(tw) { var node = this; var exp = node.expression; if (exp instanceof AST_LambdaExpression) { @@ -7522,6 +7551,7 @@ Compressor.prototype.compress = function(node) { if (fixed instanceof AST_Lambda) { mark_fn_def(tw, exp.definition(), fixed); } else { + tw.defined_ids.seq = {}; tw.find_parent(AST_Scope).may_call_this(); } return true; @@ -7626,6 +7656,13 @@ Compressor.prototype.compress = function(node) { tw.in_loop = save_loop; return true; }); + def(AST_Dot, function(tw, descend) { + descend(); + var node = this; + var expr = node.expression; + if (!node.optional && expr instanceof AST_SymbolRef) access(tw, expr.definition()); + return true; + }); def(AST_For, function(tw, descend, compressor) { var node = this; reset_block_variables(tw, compressor, node); @@ -7723,12 +7760,18 @@ Compressor.prototype.compress = function(node) { pop_scope(tw, fn); return true; }); - def(AST_Sub, function(tw) { - if (!this.optional) return; - this.expression.walk(tw); - push(tw, true); - this.property.walk(tw); - pop(tw); + def(AST_Sub, function(tw, descend) { + var node = this; + var expr = node.expression; + if (node.optional) { + expr.walk(tw); + push(tw, true); + node.property.walk(tw); + pop(tw); + } else { + descend(); + if (expr instanceof AST_SymbolRef) access(tw, expr.definition()); + } return true; }); def(AST_Switch, function(tw, descend, compressor) { @@ -7778,6 +7821,7 @@ Compressor.prototype.compress = function(node) { var d = ref.definition(); var fixed = d.fixed || d.last_ref && d.last_ref.fixed; push_ref(d, ref); + if (safe_to_access(tw, d)) ref.defined = true; if (d.references.length == 1 && !d.fixed && d.orig[0] instanceof AST_SymbolDefun) { tw.loop_ids[d.id] = tw.in_loop; } @@ -7965,6 +8009,7 @@ Compressor.prototype.compress = function(node) { return node.value || make_node(AST_Undefined, node); }, function(name, fixed) { var d = name.definition(); + assign(tw, d); if (!d.first_decl && d.references.length == 0) d.first_decl = name; if (fixed && safe_to_assign(tw, d, true)) { mark(tw, d); @@ -7997,6 +8042,7 @@ Compressor.prototype.compress = function(node) { function reset_flags(node) { node._squeezed = false; node._optimized = false; + node.single_use = false; if (node instanceof AST_BlockScope) node._var_names = undefined; if (node instanceof AST_SymbolRef) node.fixed = undefined; } @@ -8006,6 +8052,10 @@ Compressor.prototype.compress = function(node) { reset_flags(node); return node.reduce_vars(tw, descend, compressor); } : reset_flags); + // Side-effect tracking on sequential property access + tw.assigned_ids = Object.create(null); + tw.defined_ids = Object.create(null); + tw.defined_ids.seq = {}; // Flow control for visiting lambda definitions tw.fn_scanning = null; tw.fn_visited = []; @@ -9041,13 +9091,13 @@ Compressor.prototype.compress = function(node) { } if (node instanceof AST_ObjectIdentity) return symbol_in_lvalues(node, parent); if (node instanceof AST_PropAccess) { - if (side_effects) return true; var exp = node.expression; - if (exp instanceof AST_SymbolRef && is_arguments(exp.definition())) return true; if (compressor.option("unsafe")) { if (is_undeclared_ref(exp) && global_names[exp.name]) return false; if (is_static_fn(exp)) return false; } + if (exp instanceof AST_SymbolRef && is_arguments(exp.definition())) return true; + if (side_effects) return true; if (!well_defined) return true; if (value_def) return false; if (!in_try && lhs_local) return false; @@ -9056,6 +9106,7 @@ Compressor.prototype.compress = function(node) { } if (node instanceof AST_Spread) return true; if (node instanceof AST_SymbolRef) { + if (is_undeclared_ref(node) && node.is_declared(compressor)) return false; if (symbol_in_lvalues(node, parent)) return !is_direct_assignment(node, parent); if (side_effects && may_modify(node)) return true; var def = node.definition(); @@ -9075,8 +9126,10 @@ Compressor.prototype.compress = function(node) { if (sym instanceof AST_PropAccess) return true; if (check_destructured(sym)) return true; return sym.match_symbol(function(node) { - return node instanceof AST_SymbolRef - && (lvalues.has(node.name) || read_toplevel && compressor.exposed(node.definition())); + if (node instanceof AST_PropAccess) return true; + if (node instanceof AST_SymbolRef) { + return lvalues.has(node.name) || read_toplevel && compressor.exposed(node.definition()); + } }, true); function reject(node) { @@ -9672,10 +9725,14 @@ Compressor.prototype.compress = function(node) { } function update_symbols(value, node) { + var clear_defined = node instanceof AST_SymbolRef && !node.defined; var scope = node.scope || find_scope(scanner) || block_scope; value.walk(new TreeWalker(function(node) { if (node instanceof AST_BlockScope) return true; - if (node instanceof AST_Symbol) node.scope = scope; + if (node instanceof AST_Symbol) { + if (clear_defined && node instanceof AST_SymbolRef) node.defined = false; + node.scope = scope; + } })); } @@ -10688,18 +10745,18 @@ Compressor.prototype.compress = function(node) { if (prop instanceof AST_Node) return; if (!RE_POSITIVE_INTEGER.test("" + prop)) return; prop = +prop; - var len = value.elements.length; + var elements = value.elements; + var len = elements.length; if (prop > len + 4) return; + for (var i = Math.min(len, prop + 1); --i >= 0;) { + if (elements[i] instanceof AST_Spread) return; + } if (prop < len) { - var element = value.elements[prop]; - if (element instanceof AST_Hole) { - value.elements[prop] = node.right; - } else { - value.elements[prop] = make_sequence(node, [ element, node.right ]).optimize(compressor); - } + var element = elements[prop].drop_side_effect_free(compressor); + elements[prop] = element ? make_sequence(node, [ element, node.right ]) : node.right; } else { - while (prop > len) value.elements[len++] = make_node(AST_Hole, value); - value.elements[prop] = node.right; + while (prop > len) elements[len++] = make_node(AST_Hole, value); + elements[prop] = node.right; } return true; } @@ -11100,6 +11157,7 @@ Compressor.prototype.compress = function(node) { return this.tail_node()._dot_throw(compressor); }); def(AST_SymbolRef, function(compressor, force) { + if (this.defined) return false; if (this.is_undefined) return true; if (!is_strict(compressor, force)) return false; if (is_undeclared_ref(this) && this.is_declared(compressor)) return false; @@ -12590,26 +12648,8 @@ Compressor.prototype.compress = function(node) { return false; return true; } - def(AST_Node, return_false); - def(AST_Array, function(scope) { - return all_constant(this.elements, scope); - }); - def(AST_Binary, function(scope) { - return this.left.is_constant_expression(scope) - && this.right.is_constant_expression(scope) - && can_drop_op(this); - }); - def(AST_Class, function(scope) { - var base = this.extends; - if (base && !safe_for_extends(base)) return false; - return all_constant(this.properties, scope); - }); - def(AST_ClassProperty, function(scope) { - return typeof this.key == "string" && (!this.value || this.value.is_constant_expression(scope)); - }); - def(AST_Constant, return_true); - def(AST_Lambda, function(scope) { - var self = this; + + function walk_scoped(self, scope) { var result = true; var scopes = []; self.walk(new TreeWalker(function(node, descend) { @@ -12626,7 +12666,7 @@ Compressor.prototype.compress = function(node) { result = false; return true; } - if (self.variables.has(node.name)) return true; + if (self.variables && self.variables.has(node.name)) return true; var def = node.definition(); if (member(def.scope, scopes)) return true; if (scope && !def.redefined()) { @@ -12647,10 +12687,38 @@ Compressor.prototype.compress = function(node) { } })); return result; + } + + def(AST_Node, return_false); + def(AST_Array, function(scope) { + return all_constant(this.elements, scope); + }); + def(AST_Binary, function(scope) { + return this.left.is_constant_expression(scope) + && this.right.is_constant_expression(scope) + && can_drop_op(this); + }); + def(AST_Class, function(scope) { + var base = this.extends; + if (base && !safe_for_extends(base)) return false; + return all_constant(this.properties, scope); + }); + def(AST_ClassProperty, function(scope) { + if (typeof this.key != "string") return false; + var value = this.value; + if (!value) return true; + return this.static ? value.is_constant_expression(scope) : walk_scoped(value, scope); + }); + def(AST_Constant, return_true); + def(AST_Lambda, function(scope) { + return walk_scoped(this, scope); }); def(AST_Object, function(scope) { return all_constant(this.properties, scope); }); + def(AST_ObjectIdentity, function(scope) { + return this.scope.resolve() === scope; + }); def(AST_ObjectProperty, function(scope) { return typeof this.key == "string" && this.value.is_constant_expression(scope); }); @@ -14370,8 +14438,14 @@ Compressor.prototype.compress = function(node) { prop.walk(tw); }); if (node instanceof AST_Assign) { - var right = get_rhs(node), shared = false; - if (init && node.write_only === true && !right.has_side_effects(compressor)) { + var fixed = sym.fixed_value(); + var right = get_rhs(node); + var safe = fixed && fixed.is_constant(); + var shared = false; + if (init + && node.write_only === true + && (safe || node.left === sym || right.equals(sym)) + && !right.has_side_effects(compressor)) { initializations.add(node_def.id, right); } else { right.walk(tw); @@ -14381,11 +14455,8 @@ Compressor.prototype.compress = function(node) { if (!node.write_only || shared) { verify_safe_usage(node_def, sym, value_modified[node_def.id]); } - } else { - var fixed = sym.fixed_value(); - if (!fixed || !fixed.is_constant()) { - verify_safe_usage(node_def, value_read[node_def.id], true); - } + } else if (!safe) { + verify_safe_usage(node_def, value_read[node_def.id], true); } } if (track_assigns(node_def, sym) && is_lhs(sym, node) !== sym) add_assigns(node_def, sym); @@ -14471,6 +14542,7 @@ Compressor.prototype.compress = function(node) { } function trim_destructured(node, value, process, drop, root) { + var unwind = true; var trimmer = new TreeTransformer(function(node) { if (node instanceof AST_DefaultValue) { if (!(compressor.option("default_values") && value && value.is_defined(compressor))) { @@ -14488,21 +14560,27 @@ Compressor.prototype.compress = function(node) { } if (node instanceof AST_DestructuredArray) { var save_drop = drop; + var save_unwind = unwind; var save_value = value; if (value instanceof AST_SymbolRef) { drop = false; value = value.fixed_value(); } - var native, values; + var last_side_effects, native, values; if (value instanceof AST_Array) { native = true; values = value.elements; + if (save_unwind) for (last_side_effects = values.length; --last_side_effects >= 0;) { + if (values[last_side_effects].has_side_effects(compressor)) break; + } } else { native = value && value.is_string(compressor); values = false; + last_side_effects = node.elements.length; } var elements = [], newValues = drop && [], pos = 0; node.elements.forEach(function(element, index) { + if (save_unwind) unwind = index >= last_side_effects; value = values && values[index]; if (value instanceof AST_Hole) { value = null; @@ -14545,6 +14623,7 @@ Compressor.prototype.compress = function(node) { } } value = save_value; + unwind = save_unwind; drop = save_drop; if (values && newValues) { fill_holes(value, newValues); @@ -14553,22 +14632,34 @@ Compressor.prototype.compress = function(node) { } if (!native) { elements.length = node.elements.length; - } else if (!node.rest) switch (elements.length) { + } else if (!node.rest) SHORTHAND: switch (elements.length) { case 0: if (node === root) break; if (drop) value = value.drop_side_effect_free(compressor); return null; - case 1: + default: if (!drop) break; + if (!unwind) break; if (node === root) break; - var sym = elements[0]; + var pos = elements.length, sym; + while (--pos >= 0) { + var element = elements[pos]; + if (element) { + sym = element; + break; + } + } + if (pos < 0) break; + for (var i = pos; --i >= 0;) { + if (elements[i]) break SHORTHAND; + } if (sym.has_side_effects(compressor)) break; if (value.has_side_effects(compressor) && sym.match_symbol(function(node) { return node instanceof AST_PropAccess; })) break; value = make_node(AST_Sub, node, { expression: value, - property: make_node(AST_Number, node, { value: 0 }), + property: make_node(AST_Number, node, { value: pos }), }); return sym; } @@ -14578,16 +14669,19 @@ Compressor.prototype.compress = function(node) { } if (node instanceof AST_DestructuredObject) { var save_drop = drop; + var save_unwind = unwind; var save_value = value; if (value instanceof AST_SymbolRef) { drop = false; value = value.fixed_value(); } - var prop_keys, prop_map, values; + var last_side_effects, prop_keys, prop_map, values; if (value instanceof AST_Object) { + last_side_effects = -1; prop_keys = []; prop_map = new Dictionary(); values = value.properties.map(function(prop, index) { + if (save_unwind && prop.has_side_effects(compressor)) last_side_effects = index; prop = prop.clone(); if (prop instanceof AST_Spread) { prop_map = false; @@ -14603,6 +14697,8 @@ Compressor.prototype.compress = function(node) { } return prop; }); + } else { + last_side_effects = node.properties.length; } if (node.rest) { value = false; @@ -14625,6 +14721,7 @@ Compressor.prototype.compress = function(node) { return key; }).forEach(function(key, index) { var prop = node.properties[index], trimmed; + if (save_unwind) unwind = index >= last_side_effects; if (key instanceof AST_Node) { drop = false; value = false; @@ -14665,6 +14762,7 @@ Compressor.prototype.compress = function(node) { } }); value = save_value; + unwind = save_unwind; drop = save_drop; if (drop_keys && prop_keys) { value = value.clone(); @@ -14672,6 +14770,7 @@ Compressor.prototype.compress = function(node) { if (prop instanceof AST_Spread) return prop; var key = prop_keys[index]; if (key instanceof AST_Node) return prop; + if (key === "__proto__") return prop; if (drop_keys.has(key)) { var mapped = drop_keys.get(key); if (!mapped) return prop; @@ -14698,6 +14797,7 @@ Compressor.prototype.compress = function(node) { return null; case 1: if (!drop) break; + if (!unwind) break; if (node === root) break; var prop = properties[0]; if (prop.key instanceof AST_Node) break; @@ -14705,7 +14805,10 @@ Compressor.prototype.compress = function(node) { if (value.has_side_effects(compressor) && prop.value.match_symbol(function(node) { return node instanceof AST_PropAccess; })) break; - value = make_node(AST_Sub, node, { + value = is_identifier_string(prop.key) ? make_node(AST_Dot, node, { + expression: value, + property: prop.key, + }) : make_node(AST_Sub, node, { expression: value, property: make_node_from_constant(prop.key, prop), }); @@ -14822,7 +14925,8 @@ Compressor.prototype.compress = function(node) { && self.find_variable(sym.name) === sym.definition(); })) return node; node.definitions.forEach(function(defn) { - vars.set(defn.name.name, defn); + var name = defn.name.name; + if (!vars.has(name)) vars.set(name, defn); }); var seq = node.to_assignments(); if (p instanceof AST_ForEnumeration && p.init === node) { @@ -14849,13 +14953,14 @@ Compressor.prototype.compress = function(node) { return !ref.in_arg; })) vars.del(argname.name); }); - vars.each(function(defn, name) { + vars.each(function(defn) { + var name = defn.name; defn = defn.clone(); - defn.name = defn.name.clone(); + defn.name = name.clone(); defn.value = null; defns.push(defn); - vars.set(name, defn); - defn.name.definition().orig.unshift(defn.name); + var orig = name.definition().orig; + orig.splice(orig.indexOf(name), 0, defn.name); }); if (defns.length > 0) hoisted.push(make_node(AST_Var, self, { definitions: defns })); } @@ -16686,10 +16791,9 @@ Compressor.prototype.compress = function(node) { } }); def.references.push(name); + def.assignments++; } - def.assignments++; def.eliminated++; - def.single_use = false; return a; }, []); if (assignments.length == 0) return null; @@ -17312,9 +17416,11 @@ Compressor.prototype.compress = function(node) { && (value = can_flatten_body(stat))) { var replacing = exp === fn || def.single_use && def.references.length - def.replaced == 1; if (can_substitute_directly()) { + self._optimized = true; + var retValue = value.optimize(compressor).clone(true); var args = self.args.slice(); var refs = []; - var retValue = value.clone(true).transform(new TreeTransformer(function(node) { + retValue = retValue.transform(new TreeTransformer(function(node) { if (node instanceof AST_SymbolRef) { var def = node.definition(); if (fn.variables.get(node.name) !== def) { @@ -17546,6 +17652,10 @@ Compressor.prototype.compress = function(node) { return; } if (node instanceof AST_Class) return abort = true; + if (node instanceof AST_Destructured) { + side_effects = true; + return; + } if (node instanceof AST_Scope) return abort = true; if (avoid && node instanceof AST_Symbol && avoid[node.name]) return abort = true; if (node instanceof AST_SymbolRef) { @@ -18398,7 +18508,11 @@ Compressor.prototype.compress = function(node) { var exprs = []; if (self.left.evaluate(compressor) instanceof AST_Node) exprs.push(self.left); if (self.right.evaluate(compressor) instanceof AST_Node) exprs.push(self.right); - if (exprs.length < 2) { + switch (exprs.length) { + case 0: + return make_node(AST_True, self).optimize(compressor); + case 1: + exprs[0] = exprs[0].clone(); exprs.push(make_node(AST_True, self)); return make_sequence(self, exprs).optimize(compressor); } @@ -18994,7 +19108,8 @@ Compressor.prototype.compress = function(node) { single_use = false; } else if (fixed.has_side_effects(compressor)) { single_use = false; - } else if (compressor.option("ie") && fixed instanceof AST_Class) { + } else if (fixed instanceof AST_Class + && (compressor.option("ie") || !fixed.is_constant_expression(self.scope))) { single_use = false; } if (single_use) fixed.parent_scope = self.scope; @@ -19333,24 +19448,23 @@ Compressor.prototype.compress = function(node) { if (compressor.option("dead_code")) { if (self.left instanceof AST_PropAccess) { if (self.operator == "=") { - if (self.redundant) { - var exprs = [ self.left.expression ]; - if (self.left instanceof AST_Sub) exprs.push(self.left.property); - exprs.push(self.right); - return make_sequence(self, exprs).optimize(compressor); - } - if (self.left.equals(self.right) && !self.left.has_side_effects(compressor)) { - return self.right; - } var exp = self.left.expression; + if (self.left.equals(self.right)) { + var defined = exp.defined; + exp.defined = false; + var drop_lhs = !self.left.has_side_effects(compressor); + exp.defined = defined; + if (drop_lhs) return self.right; + } if (exp instanceof AST_Lambda || !compressor.has_directive("use strict") && exp instanceof AST_Constant && !exp.may_throw_on_access(compressor)) { - return self.left instanceof AST_Dot ? self.right : make_sequence(self, [ + var value = self.left instanceof AST_Dot ? self.right : make_sequence(self, [ self.left.property, - self.right - ]).optimize(compressor); + self.right, + ]); + return maintain_this_binding(compressor.parent(), self, value).optimize(compressor); } } } else if (self.left instanceof AST_SymbolRef && can_drop_symbol(self.left, compressor)) { @@ -20458,6 +20572,7 @@ Compressor.prototype.compress = function(node) { var fn = call.expression; if (!(fn instanceof AST_LambdaExpression)) return; if (fn.name) return; + if (fn.single_use) return; if (fn.uses_arguments) return; if (fn.pinned()) return; if (is_generator(fn)) return; @@ -20550,7 +20665,8 @@ Compressor.prototype.compress = function(node) { stat.walk(new TreeWalker(function(node) { if (abort) return true; if (node instanceof AST_Try) { - if (node.bfinally && all(node.body, function(stat) { + if (!node.bfinally) return; + if (all(node.body, function(stat) { stat.walk(find_return); return !abort; }) && node.bcatch) node.bcatch.walk(find_return); @@ -21132,7 +21248,9 @@ function OutputStream(options) { if (line_fixed || flush) flush_mappings(); } : noop; - var require_semicolon = makePredicate("( [ + * / - , ."); + var stat_end_chars = makePredicate("; }"); + var asi_skip_chars = makePredicate("( [ + * / - , . `"); + var asi_skip_words = makePredicate("in instanceof"); function require_space(prev, ch, str) { return is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\") @@ -21168,8 +21286,8 @@ function OutputStream(options) { var prev = last.slice(-1); if (might_need_semicolon) { might_need_semicolon = false; - if (prev == ":" && ch == "}" || prev != ";" && (!ch || ";}".indexOf(ch) < 0)) { - var need_semicolon = require_semicolon[ch]; + if (prev != ";" && !stat_end_chars[ch]) { + var need_semicolon = asi_skip_chars[ch] || asi_skip_words[str]; if (need_semicolon || options.semicolons) { output += ";"; current_col++; @@ -21814,7 +21932,12 @@ function OutputStream(options) { DEFPRINT(AST_LabeledStatement, function(output) { this.label.print(output); output.colon(); - this.body.print(output); + var body = this.body; + if (body instanceof AST_EmptyStatement) { + output.force_semicolon(); + } else { + body.print(output); + } }); DEFPRINT(AST_SimpleStatement, function(output) { this.body.print(output); @@ -22117,6 +22240,12 @@ function OutputStream(options) { output.print("="); output.space(); self.value.print(output); + } else switch (self.key) { + case "get": + case "set": + case "static": + output.force_semicolon(); + return; } output.semicolon(); }); diff --git a/package.json b/package.json index abad909..e978175 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "uglify-js-export", - "version": "3.18.0", + "version": "3.19.0", "description": "A transform to make UglifyJS work in browserify.", "homepage": "https://jaywcjlove.github.io/tools/#/js-beautifier", "funding": "https://jaywcjlove.github.io/#/sponsor",