fix corner case in hoist_props (#3452)

fixes #3440
This commit is contained in:
Alex Lam S.L
2019-10-06 10:29:13 +08:00
committed by GitHub
parent 35338a100f
commit 931ac66638
2 changed files with 73 additions and 41 deletions

View File

@@ -4062,10 +4062,11 @@ merge(Compressor.prototype, {
var top_retain = self instanceof AST_Toplevel && compressor.top_retain || return_false; var top_retain = self instanceof AST_Toplevel && compressor.top_retain || return_false;
var defs_by_id = Object.create(null); var defs_by_id = Object.create(null);
self.transform(new TreeTransformer(function(node, descend) { self.transform(new TreeTransformer(function(node, descend) {
if (node instanceof AST_Assign if (node instanceof AST_Assign) {
&& node.operator == "=" if (node.operator != "=") return;
&& node.write_only if (!node.write_only) return;
&& can_hoist(node.left, node.right, 1)) { if (node.left.scope !== self) return;
if (!can_hoist(node.left, node.right, 1)) return;
descend(node, this); descend(node, this);
var defs = new Dictionary(); var defs = new Dictionary();
var assignments = []; var assignments = [];
@@ -4094,17 +4095,9 @@ merge(Compressor.prototype, {
})); }));
return make_sequence(node, assignments); return make_sequence(node, assignments);
} }
if (node instanceof AST_Unary if (node instanceof AST_Scope) return node === self ? undefined : node;
&& !unary_side_effects[node.operator] if (node instanceof AST_VarDef) {
&& node.expression instanceof AST_SymbolRef if (!can_hoist(node.name, node.value, 0)) return;
&& 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)) {
descend(node, this); descend(node, this);
var defs = new Dictionary(); var defs = new Dictionary();
var var_defs = []; var var_defs = [];
@@ -4117,32 +4110,6 @@ merge(Compressor.prototype, {
defs_by_id[node.name.definition().id] = defs; defs_by_id[node.name.definition().id] = defs;
return MAP.splice(var_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) { function make_sym(sym, key) {
var new_var = make_node(AST_SymbolVar, sym, { var new_var = make_node(AST_SymbolVar, sym, {
@@ -4155,6 +4122,43 @@ merge(Compressor.prototype, {
return new_var; 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() // drop_side_effect_free()

View File

@@ -886,3 +886,31 @@ issue_3411: {
} }
expect_stdout: "PASS" expect_stdout: "PASS"
} }
issue_3440: {
options = {
hoist_props: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
function f() {
console.log(o.p);
}
var o = {
p: "PASS",
};
return f;
})()();
}
expect: {
(function() {
var o_p = "PASS";
return function() {
console.log(o_p);
};
})()();
}
expect_stdout: "PASS"
}