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 = [];
}));
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 = [];
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, {
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()