From: Alex Lam S.L Date: Wed, 2 Sep 2020 03:30:46 +0000 (+0100) Subject: enhance `reduce_vars` (#4088) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=2500930234304c89d6b9a87cb95fe07d1a8bc6c5;p=UglifyJS.git enhance `reduce_vars` (#4088) --- diff --git a/lib/compress.js b/lib/compress.js index 2c21217e..6761c246 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -325,22 +325,22 @@ merge(Compressor.prototype, { } var lhs = is_lhs(node, parent); if (lhs) return lhs; - if (!immutable - && parent instanceof AST_Call - && parent.expression === node - && !parent.is_expr_pure(compressor) - && (!(value instanceof AST_Function) - || !(parent instanceof AST_New) && value.contains_this())) { - return true; - } - if (parent instanceof AST_Array) { - return is_modified(compressor, tw, parent, parent, level + 1); - } - if (parent instanceof AST_ObjectKeyVal && node === parent.value) { + if (parent instanceof AST_Array) return is_modified(compressor, tw, parent, parent, level + 1); + if (parent instanceof AST_Call) { + return !immutable + && parent.expression === node + && !parent.is_expr_pure(compressor) + && (!(value instanceof AST_Function) + || !(parent instanceof AST_New) && value.contains_this()); + } + if (parent instanceof AST_ForIn) return parent.init === node; + if (parent instanceof AST_ObjectKeyVal) { + if (parent.value !== node) return; var obj = tw.parent(level + 1); return is_modified(compressor, tw, obj, obj, level + 2); } - if (parent instanceof AST_PropAccess && parent.expression === node) { + if (parent instanceof AST_PropAccess) { + if (parent.expression !== node) return; var prop = read_property(value, parent); return (!immutable || recursive) && is_modified(compressor, tw, parent, prop, level + 1); } @@ -514,33 +514,41 @@ merge(Compressor.prototype, { || value instanceof AST_This; } + function has_escaped(d, node, parent) { + if (parent instanceof AST_Assign) return parent.operator == "=" && parent.right === node; + if (parent instanceof AST_Call) return parent.expression !== node || parent instanceof AST_New; + if (parent instanceof AST_Exit) return parent.value === node && node.scope !== d.scope; + if (parent instanceof AST_VarDef) return parent.value === node; + } + + function value_in_use(node, parent) { + if (parent instanceof AST_Array) return true; + if (parent instanceof AST_Binary) return lazy_op[parent.operator]; + if (parent instanceof AST_Conditional) return parent.condition !== node; + if (parent instanceof AST_Sequence) return parent.tail_node() === node; + } + function mark_escaped(tw, d, scope, node, value, level, depth) { var parent = tw.parent(level); if (value && value.is_constant()) return; - if (parent instanceof AST_Assign && parent.operator == "=" && node === parent.right - || parent instanceof AST_Call && (node !== parent.expression || parent instanceof AST_New) - || parent instanceof AST_Exit && node === parent.value && node.scope !== d.scope - || parent instanceof AST_VarDef && node === parent.value) { + if (has_escaped(d, node, parent)) { d.escaped.push(parent); if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1; if (!d.escaped.depth || d.escaped.depth > depth) d.escaped.depth = depth; return; - } else if (parent instanceof AST_Array - || parent instanceof AST_Binary && lazy_op[parent.operator] - || parent instanceof AST_Conditional && node !== parent.condition - || parent instanceof AST_Sequence && node === parent.tail_node()) { + } else if (value_in_use(node, parent)) { mark_escaped(tw, d, scope, parent, parent, level + 1, depth); - } else if (parent instanceof AST_ObjectKeyVal && node === parent.value) { + } else if (parent instanceof AST_ObjectKeyVal && parent.value === node) { var obj = tw.parent(level + 1); mark_escaped(tw, d, scope, obj, obj, level + 2, depth); - } else if (parent instanceof AST_PropAccess && node === parent.expression) { + } else if (parent instanceof AST_PropAccess && parent.expression === node) { value = read_property(value, parent); mark_escaped(tw, d, scope, parent, value, level + 1, depth + 1); if (value) return; } if (level > 0) return; - if (parent instanceof AST_Call && node === parent.expression) return; - if (parent instanceof AST_Sequence && node !== parent.tail_node()) return; + if (parent instanceof AST_Call && parent.expression === node) return; + if (parent instanceof AST_Sequence && parent.tail_node() !== node) return; if (parent instanceof AST_SimpleStatement) return; if (parent instanceof AST_Unary && !unary_side_effects[parent.operator]) return; d.direct_access = true; @@ -739,13 +747,11 @@ merge(Compressor.prototype, { push(tw); var init = this.init; init.walk(tw); - if (init instanceof AST_Var) { - init = init.definitions[0].name; - } else while (init instanceof AST_PropAccess) { - init = init.expression.tail_node(); + if (init instanceof AST_SymbolRef) { + init.definition().fixed = false; + } else if (init instanceof AST_Var) { + init.definitions[0].name.definition().fixed = false; } - var def = init.definition(); - if (def) def.fixed = false; this.body.walk(tw); pop(tw); tw.in_loop = saved_loop;