diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compress.js | 93 |
1 files changed, 71 insertions, 22 deletions
diff --git a/lib/compress.js b/lib/compress.js index 2c60a9b6..e18fd575 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1124,7 +1124,7 @@ merge(Compressor.prototype, { hit_index++; if (hit_index < hit_stack.length) return handle_custom_scan_order(node); hit = true; - stop_after = find_stop(node, 0); + stop_after = (value_def ? find_stop_value : find_stop)(node, 0); if (stop_after === node) abort = true; return node; } @@ -1540,46 +1540,95 @@ merge(Compressor.prototype, { function find_stop(node, level) { var parent = scanner.parent(level); - if (parent instanceof AST_Array) return value_def ? find_stop(parent, level + 1) : node; + if (parent instanceof AST_Array) return node; + if (parent instanceof AST_Assign) return node; + if (parent instanceof AST_Binary) return node; + if (parent instanceof AST_Call) return node; + if (parent instanceof AST_Case) return node; + if (parent instanceof AST_Conditional) return node; + if (parent instanceof AST_Definitions) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_Exit) return node; + if (parent instanceof AST_If) return node; + if (parent instanceof AST_IterationStatement) return node; + if (parent instanceof AST_ObjectKeyVal) return node; + if (parent instanceof AST_PropAccess) return node; + if (parent instanceof AST_Sequence) { + return (parent.tail_node() === node ? find_stop : find_stop_unused)(parent, level + 1); + } + if (parent instanceof AST_SimpleStatement) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_Switch) return node; + if (parent instanceof AST_Unary) return node; + if (parent instanceof AST_VarDef) return node; + return null; + } + + function find_stop_value(node, level) { + var parent = scanner.parent(level); + if (parent instanceof AST_Array) return find_stop_value(parent, level + 1); if (parent instanceof AST_Assign) { - if (!value_def) return node; - if (lhs.equivalent_to(parent.left)) return node; - if (get_rvalue(candidate).equivalent_to(parent.left)) return node; - return find_stop(parent, level + 1); + if (parent.left instanceof AST_SymbolRef) { + var name = parent.left.name; + if (lhs.name == name) return node; + if (value_def.name == name) return node; + } + return find_stop_value(parent, level + 1); } if (parent instanceof AST_Binary) { - if (!value_def) return node; if (lazy_op[parent.operator] && parent.left !== node) { var grandparent = scanner.parent(level + 1); if (!(grandparent instanceof AST_Binary)) return node; if (grandparent.operator != parent.operator) return node; } - return find_stop(parent, level + 1); + return find_stop_value(parent, level + 1); + } + if (parent instanceof AST_Call) return parent; + if (parent instanceof AST_Case) { + if (parent.expression !== node) return node; + return find_stop_value(parent, level + 1); } - if (parent instanceof AST_Call) return value_def ? parent : node; - if (parent instanceof AST_Case) return node; if (parent instanceof AST_Conditional) { - if (!value_def || parent.condition !== node) return node; - return find_stop(parent, level + 1); + if (parent.condition !== node) return node; + return find_stop_value(parent, level + 1); } if (parent instanceof AST_Definitions) return find_stop_unused(parent, level + 1); - if (parent instanceof AST_Exit) return node; - if (parent instanceof AST_If) return node; - if (parent instanceof AST_IterationStatement) return node; - if (parent instanceof AST_ObjectKeyVal) { - return value_def ? find_stop(scanner.parent(level + 1), level + 2) : node; + if (parent instanceof AST_Do) return node; + if (parent instanceof AST_Exit) return find_stop_unused(parent, level + 1); + if (parent instanceof AST_For) { + if (parent.init !== node && parent.condition !== node) return node; + return find_stop_value(parent, level + 1); } - if (parent instanceof AST_PropAccess) return node; + if (parent instanceof AST_ForIn) { + if (parent.init !== node) return node; + return find_stop_value(parent, level + 1); + } + if (parent instanceof AST_If) { + if (parent.condition !== node) return node; + return find_stop_value(parent, level + 1); + } + if (parent instanceof AST_ObjectKeyVal) return find_stop_value(scanner.parent(level + 1), level + 2); + if (parent instanceof AST_PropAccess) return find_stop_value(parent, level + 1); if (parent instanceof AST_Sequence) { - return (parent.tail_node() === node ? find_stop : find_stop_unused)(parent, level + 1); + return (parent.tail_node() === node ? find_stop_value : find_stop_unused)(parent, level + 1); } if (parent instanceof AST_SimpleStatement) return find_stop_unused(parent, level + 1); - if (parent instanceof AST_Switch) return node; + if (parent instanceof AST_Switch) { + if (parent.expression !== node) return node; + return find_stop_value(parent, level + 1); + } if (parent instanceof AST_Unary) { if (parent.operator == "delete") return node; - return value_def ? find_stop(parent, level + 1) : node; + return find_stop_value(parent, level + 1); + } + if (parent instanceof AST_VarDef) { + var name = parent.name.name; + if (lhs.name == name) return node; + if (value_def.name == name) return node; + return find_stop_value(parent, level + 1); + } + if (parent instanceof AST_While) { + if (parent.condition !== node) return node; + return find_stop_value(parent, level + 1); } - if (parent instanceof AST_VarDef) return node; return null; } |