diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2019-10-06 10:29:13 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-06 10:29:13 +0800 |
commit | 931ac666382081a80267ab01ecfa5712162d5837 (patch) | |
tree | 9024632453f6ee9a339e47e9c761ddfb91758325 /lib/compress.js | |
parent | 35338a100f62d881de06eebdaa1ed98c7212cfc4 (diff) | |
download | tracifyjs-931ac666382081a80267ab01ecfa5712162d5837.tar.gz tracifyjs-931ac666382081a80267ab01ecfa5712162d5837.zip |
fix corner case in `hoist_props` (#3452)
fixes #3440
Diffstat (limited to 'lib/compress.js')
-rw-r--r-- | lib/compress.js | 86 |
1 files changed, 45 insertions, 41 deletions
diff --git a/lib/compress.js b/lib/compress.js index ade1913c..5ea5d00b 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -4062,10 +4062,11 @@ merge(Compressor.prototype, { var top_retain = self instanceof AST_Toplevel && compressor.top_retain || return_false; var defs_by_id = Object.create(null); self.transform(new TreeTransformer(function(node, descend) { - if (node instanceof AST_Assign - && node.operator == "=" - && node.write_only - && can_hoist(node.left, node.right, 1)) { + if (node instanceof AST_Assign) { + if (node.operator != "=") return; + if (!node.write_only) return; + if (node.left.scope !== self) return; + if (!can_hoist(node.left, node.right, 1)) return; descend(node, this); var defs = new Dictionary(); var assignments = []; @@ -4094,17 +4095,9 @@ merge(Compressor.prototype, { })); return make_sequence(node, assignments); } - if (node instanceof AST_Unary - && !unary_side_effects[node.operator] - && node.expression instanceof AST_SymbolRef - && node.expression.definition().id in defs_by_id) { - node = node.clone(); - node.expression = make_node(AST_Object, node, { - properties: [] - }); - return node; - } - if (node instanceof AST_VarDef && can_hoist(node.name, node.value, 0)) { + if (node instanceof AST_Scope) return node === self ? undefined : node; + if (node instanceof AST_VarDef) { + if (!can_hoist(node.name, node.value, 0)) return; descend(node, this); var defs = new Dictionary(); var var_defs = []; @@ -4117,32 +4110,6 @@ merge(Compressor.prototype, { defs_by_id[node.name.definition().id] = defs; return MAP.splice(var_defs); } - if (node instanceof AST_PropAccess && node.expression instanceof AST_SymbolRef) { - var defs = defs_by_id[node.expression.definition().id]; - if (defs) { - var def = defs.get(node.getProperty()); - var sym = make_node(AST_SymbolRef, node, { - name: def.name, - scope: node.expression.scope, - thedef: def - }); - sym.reference({}); - return sym; - } - } - - function can_hoist(sym, right, count) { - if (sym.scope !== self) return; - var def = sym.definition(); - if (def.assignments != count) return; - if (def.direct_access) return; - if (def.escaped.depth == 1) return; - if (def.references.length == count) return; - if (def.single_use) return; - if (top_retain(def)) return; - if (sym.fixed_value() !== right) return; - return right instanceof AST_Object; - } function make_sym(sym, key) { var new_var = make_node(AST_SymbolVar, sym, { @@ -4155,6 +4122,43 @@ merge(Compressor.prototype, { return new_var; } })); + self.transform(new TreeTransformer(function(node, descend) { + if (node instanceof AST_PropAccess) { + if (!(node.expression instanceof AST_SymbolRef)) return; + var defs = defs_by_id[node.expression.definition().id]; + if (!defs) return; + var def = defs.get(node.getProperty()); + var sym = make_node(AST_SymbolRef, node, { + name: def.name, + scope: node.expression.scope, + thedef: def + }); + sym.reference({}); + return sym; + } + if (node instanceof AST_Unary) { + if (unary_side_effects[node.operator]) return; + if (!(node.expression instanceof AST_SymbolRef)) return; + if (!(node.expression.definition().id in defs_by_id)) return; + var opt = node.clone(); + opt.expression = make_node(AST_Object, node, { + properties: [] + }); + return opt; + } + })); + + function can_hoist(sym, right, count) { + var def = sym.definition(); + if (def.assignments != count) return; + if (def.direct_access) return; + if (def.escaped.depth == 1) return; + if (def.references.length == count) return; + if (def.single_use) return; + if (top_retain(def)) return; + if (sym.fixed_value() !== right) return; + return right instanceof AST_Object; + } }); // drop_side_effect_free() |