Compare commits

..

No commits in common. "master" and "v3.18.0" have entirely different histories.

17 changed files with 92 additions and 1170 deletions

View File

@ -779,11 +779,11 @@ to be `false` and all symbol names will be omitted.
overhead (compression will be slower). Make sure symbols under `pure_funcs` overhead (compression will be slower). Make sure symbols under `pure_funcs`
are also under `mangle.reserved` to avoid mangling. are also under `mangle.reserved` to avoid mangling.
- `pure_getters` (default: `"strict"`) — Pass `true` for UglifyJS to assume that - `pure_getters` (default: `"strict"`) — If you pass `true` for
object property access (e.g. `foo.bar` or `a[42]`) does not throw exception or this, UglifyJS will assume that object property access
alter program states via getter function. Pass `"strict"` to allow dropping or (e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects.
reordering `foo.bar` only if `foo` is not `null` or `undefined` and is safe to Specify `"strict"` to treat `foo.bar` as side-effect-free only when
access as a variable. Pass `false` to retain all property accesses. `foo` is certain to not throw, i.e. not `null` or `undefined`.
- `reduce_funcs` (default: `true`) — Allows single-use functions to be - `reduce_funcs` (default: `true`) — Allows single-use functions to be
inlined as function expressions when permissible allowing further inlined as function expressions when permissible allowing further

View File

@ -169,6 +169,8 @@ DEF_BITPROPS(AST_Node, [
"private", "private",
// AST_Call // AST_Call
"pure", "pure",
// AST_Assign
"redundant",
// AST_Node // AST_Node
"single_use", "single_use",
// AST_ClassProperty // AST_ClassProperty

View File

@ -185,7 +185,7 @@ function Compressor(options, false_by_default) {
}; };
} }
Compressor.prototype = new TreeTransformer(function(node, descend) { Compressor.prototype = new TreeTransformer(function(node, descend, in_list) {
if (node._squeezed) return node; if (node._squeezed) return node;
var is_scope = node instanceof AST_Scope; var is_scope = node instanceof AST_Scope;
if (is_scope) { if (is_scope) {
@ -270,7 +270,7 @@ Compressor.prototype.compress = function(node) {
}; };
(function(OPT) { (function(OPT) {
OPT(AST_Node, function(self) { OPT(AST_Node, function(self, compressor) {
return self; return self;
}); });
@ -638,30 +638,15 @@ Compressor.prototype.compress = function(node) {
} }
function push(tw, sequential) { function push(tw, sequential) {
var defined_ids = Object.create(tw.defined_ids);
var safe_ids = Object.create(tw.safe_ids); var safe_ids = Object.create(tw.safe_ids);
if (!sequential) { if (!sequential) safe_ids.seq = {};
defined_ids.seq = {};
safe_ids.seq = {};
}
tw.defined_ids = defined_ids;
tw.safe_ids = safe_ids; tw.safe_ids = safe_ids;
} }
function pop(tw) { function pop(tw) {
tw.defined_ids = Object.getPrototypeOf(tw.defined_ids);
tw.safe_ids = Object.getPrototypeOf(tw.safe_ids); tw.safe_ids = Object.getPrototypeOf(tw.safe_ids);
} }
function access(tw, def) {
tw.defined_ids[def.id] = [ tw.defined_ids.seq ];
}
function assign(tw, def) {
var defined = tw.defined_ids[def.id];
if (defined) defined[0] = false;
}
function mark(tw, def) { function mark(tw, def) {
tw.safe_ids[def.id] = {}; tw.safe_ids[def.id] = {};
} }
@ -954,13 +939,9 @@ Compressor.prototype.compress = function(node) {
return fixed_node; return fixed_node;
}, visit); }, visit);
walk_lambda(fn, tw); walk_lambda(fn, tw);
var defined_ids = tw.defined_ids;
var safe_ids = tw.safe_ids; var safe_ids = tw.safe_ids;
pop_scope(tw, fn); pop_scope(tw, fn);
if (!aborts) { if (!aborts) tw.safe_ids = safe_ids;
tw.defined_ids = defined_ids;
tw.safe_ids = safe_ids;
}
return true; return true;
function visit(node, fixed) { function visit(node, fixed) {
@ -988,6 +969,7 @@ Compressor.prototype.compress = function(node) {
if (left.equals(right) && !left.has_side_effects(compressor)) { if (left.equals(right) && !left.has_side_effects(compressor)) {
right.walk(tw); right.walk(tw);
walk_prop(left); walk_prop(left);
node.redundant = true;
return true; return true;
} }
if (ld && right instanceof AST_LambdaExpression) { if (ld && right instanceof AST_LambdaExpression) {
@ -1013,7 +995,6 @@ Compressor.prototype.compress = function(node) {
mark_assignment_to_arguments(left); mark_assignment_to_arguments(left);
return walk_lazy(); return walk_lazy();
} }
assign(tw, ld);
ld.assignments++; ld.assignments++;
var fixed = ld.fixed; var fixed = ld.fixed;
if (is_modified(compressor, tw, node, node, 0)) { if (is_modified(compressor, tw, node, node, 0)) {
@ -1082,7 +1063,6 @@ Compressor.prototype.compress = function(node) {
return; return;
} }
var d = sym.definition(); var d = sym.definition();
assign(tw, d);
d.assignments++; d.assignments++;
if (!fixed || sym.in_arg || !safe_to_assign(tw, d)) { if (!fixed || sym.in_arg || !safe_to_assign(tw, d)) {
walk(); walk();
@ -1123,7 +1103,7 @@ Compressor.prototype.compress = function(node) {
def(AST_BlockScope, function(tw, descend, compressor) { def(AST_BlockScope, function(tw, descend, compressor) {
reset_block_variables(tw, compressor, this); reset_block_variables(tw, compressor, this);
}); });
def(AST_Call, function(tw) { def(AST_Call, function(tw, descend) {
var node = this; var node = this;
var exp = node.expression; var exp = node.expression;
if (exp instanceof AST_LambdaExpression) { if (exp instanceof AST_LambdaExpression) {
@ -1154,7 +1134,6 @@ Compressor.prototype.compress = function(node) {
if (fixed instanceof AST_Lambda) { if (fixed instanceof AST_Lambda) {
mark_fn_def(tw, exp.definition(), fixed); mark_fn_def(tw, exp.definition(), fixed);
} else { } else {
tw.defined_ids.seq = {};
tw.find_parent(AST_Scope).may_call_this(); tw.find_parent(AST_Scope).may_call_this();
} }
return true; return true;
@ -1259,13 +1238,6 @@ Compressor.prototype.compress = function(node) {
tw.in_loop = save_loop; tw.in_loop = save_loop;
return true; return true;
}); });
def(AST_Dot, function(tw, descend) {
descend();
var node = this;
var expr = node.expression;
if (!node.optional && expr instanceof AST_SymbolRef) access(tw, expr.definition());
return true;
});
def(AST_For, function(tw, descend, compressor) { def(AST_For, function(tw, descend, compressor) {
var node = this; var node = this;
reset_block_variables(tw, compressor, node); reset_block_variables(tw, compressor, node);
@ -1363,18 +1335,12 @@ Compressor.prototype.compress = function(node) {
pop_scope(tw, fn); pop_scope(tw, fn);
return true; return true;
}); });
def(AST_Sub, function(tw, descend) { def(AST_Sub, function(tw) {
var node = this; if (!this.optional) return;
var expr = node.expression; this.expression.walk(tw);
if (node.optional) { push(tw, true);
expr.walk(tw); this.property.walk(tw);
push(tw, true); pop(tw);
node.property.walk(tw);
pop(tw);
} else {
descend();
if (expr instanceof AST_SymbolRef) access(tw, expr.definition());
}
return true; return true;
}); });
def(AST_Switch, function(tw, descend, compressor) { def(AST_Switch, function(tw, descend, compressor) {
@ -1424,8 +1390,6 @@ Compressor.prototype.compress = function(node) {
var d = ref.definition(); var d = ref.definition();
var fixed = d.fixed || d.last_ref && d.last_ref.fixed; var fixed = d.fixed || d.last_ref && d.last_ref.fixed;
push_ref(d, ref); push_ref(d, ref);
var defined = tw.defined_ids[d.id];
if (defined && defined[0] === tw.defined_ids.seq) ref.defined = true;
if (d.references.length == 1 && !d.fixed && d.orig[0] instanceof AST_SymbolDefun) { if (d.references.length == 1 && !d.fixed && d.orig[0] instanceof AST_SymbolDefun) {
tw.loop_ids[d.id] = tw.in_loop; tw.loop_ids[d.id] = tw.in_loop;
} }
@ -1613,7 +1577,6 @@ Compressor.prototype.compress = function(node) {
return node.value || make_node(AST_Undefined, node); return node.value || make_node(AST_Undefined, node);
}, function(name, fixed) { }, function(name, fixed) {
var d = name.definition(); var d = name.definition();
assign(tw, d);
if (!d.first_decl && d.references.length == 0) d.first_decl = name; if (!d.first_decl && d.references.length == 0) d.first_decl = name;
if (fixed && safe_to_assign(tw, d, true)) { if (fixed && safe_to_assign(tw, d, true)) {
mark(tw, d); mark(tw, d);
@ -1655,9 +1618,6 @@ Compressor.prototype.compress = function(node) {
reset_flags(node); reset_flags(node);
return node.reduce_vars(tw, descend, compressor); return node.reduce_vars(tw, descend, compressor);
} : reset_flags); } : reset_flags);
// Side-effect tracking on sequential property access
tw.defined_ids = Object.create(null);
tw.defined_ids.seq = {};
// Flow control for visiting lambda definitions // Flow control for visiting lambda definitions
tw.fn_scanning = null; tw.fn_scanning = null;
tw.fn_visited = []; tw.fn_visited = [];
@ -2693,13 +2653,13 @@ Compressor.prototype.compress = function(node) {
} }
if (node instanceof AST_ObjectIdentity) return symbol_in_lvalues(node, parent); if (node instanceof AST_ObjectIdentity) return symbol_in_lvalues(node, parent);
if (node instanceof AST_PropAccess) { if (node instanceof AST_PropAccess) {
if (side_effects) return true;
var exp = node.expression; var exp = node.expression;
if (exp instanceof AST_SymbolRef && is_arguments(exp.definition())) return true;
if (compressor.option("unsafe")) { if (compressor.option("unsafe")) {
if (is_undeclared_ref(exp) && global_names[exp.name]) return false; if (is_undeclared_ref(exp) && global_names[exp.name]) return false;
if (is_static_fn(exp)) return false; if (is_static_fn(exp)) return false;
} }
if (exp instanceof AST_SymbolRef && is_arguments(exp.definition())) return true;
if (side_effects) return true;
if (!well_defined) return true; if (!well_defined) return true;
if (value_def) return false; if (value_def) return false;
if (!in_try && lhs_local) return false; if (!in_try && lhs_local) return false;
@ -2708,7 +2668,6 @@ Compressor.prototype.compress = function(node) {
} }
if (node instanceof AST_Spread) return true; if (node instanceof AST_Spread) return true;
if (node instanceof AST_SymbolRef) { if (node instanceof AST_SymbolRef) {
if (is_undeclared_ref(node) && node.is_declared(compressor)) return false;
if (symbol_in_lvalues(node, parent)) return !is_direct_assignment(node, parent); if (symbol_in_lvalues(node, parent)) return !is_direct_assignment(node, parent);
if (side_effects && may_modify(node)) return true; if (side_effects && may_modify(node)) return true;
var def = node.definition(); var def = node.definition();
@ -2728,10 +2687,8 @@ Compressor.prototype.compress = function(node) {
if (sym instanceof AST_PropAccess) return true; if (sym instanceof AST_PropAccess) return true;
if (check_destructured(sym)) return true; if (check_destructured(sym)) return true;
return sym.match_symbol(function(node) { return sym.match_symbol(function(node) {
if (node instanceof AST_PropAccess) return true; return node instanceof AST_SymbolRef
if (node instanceof AST_SymbolRef) { && (lvalues.has(node.name) || read_toplevel && compressor.exposed(node.definition()));
return lvalues.has(node.name) || read_toplevel && compressor.exposed(node.definition());
}
}, true); }, true);
function reject(node) { function reject(node) {
@ -3327,14 +3284,10 @@ Compressor.prototype.compress = function(node) {
} }
function update_symbols(value, node) { function update_symbols(value, node) {
var clear_defined = node instanceof AST_SymbolRef && !node.defined;
var scope = node.scope || find_scope(scanner) || block_scope; var scope = node.scope || find_scope(scanner) || block_scope;
value.walk(new TreeWalker(function(node) { value.walk(new TreeWalker(function(node) {
if (node instanceof AST_BlockScope) return true; if (node instanceof AST_BlockScope) return true;
if (node instanceof AST_Symbol) { if (node instanceof AST_Symbol) node.scope = scope;
if (clear_defined && node instanceof AST_SymbolRef) node.defined = false;
node.scope = scope;
}
})); }));
} }
@ -4347,18 +4300,18 @@ Compressor.prototype.compress = function(node) {
if (prop instanceof AST_Node) return; if (prop instanceof AST_Node) return;
if (!RE_POSITIVE_INTEGER.test("" + prop)) return; if (!RE_POSITIVE_INTEGER.test("" + prop)) return;
prop = +prop; prop = +prop;
var elements = value.elements; var len = value.elements.length;
var len = elements.length;
if (prop > len + 4) return; if (prop > len + 4) return;
for (var i = Math.min(len, prop + 1); --i >= 0;) {
if (elements[i] instanceof AST_Spread) return;
}
if (prop < len) { if (prop < len) {
var element = elements[prop].drop_side_effect_free(compressor); var element = value.elements[prop];
elements[prop] = element ? make_sequence(node, [ element, node.right ]) : node.right; if (element instanceof AST_Hole) {
value.elements[prop] = node.right;
} else {
value.elements[prop] = make_sequence(node, [ element, node.right ]).optimize(compressor);
}
} else { } else {
while (prop > len) elements[len++] = make_node(AST_Hole, value); while (prop > len) value.elements[len++] = make_node(AST_Hole, value);
elements[prop] = node.right; value.elements[prop] = node.right;
} }
return true; return true;
} }
@ -4759,7 +4712,6 @@ Compressor.prototype.compress = function(node) {
return this.tail_node()._dot_throw(compressor); return this.tail_node()._dot_throw(compressor);
}); });
def(AST_SymbolRef, function(compressor, force) { def(AST_SymbolRef, function(compressor, force) {
if (this.defined) return false;
if (this.is_undefined) return true; if (this.is_undefined) return true;
if (!is_strict(compressor, force)) return false; if (!is_strict(compressor, force)) return false;
if (is_undeclared_ref(this) && this.is_declared(compressor)) return false; if (is_undeclared_ref(this) && this.is_declared(compressor)) return false;
@ -8030,14 +7982,8 @@ Compressor.prototype.compress = function(node) {
prop.walk(tw); prop.walk(tw);
}); });
if (node instanceof AST_Assign) { if (node instanceof AST_Assign) {
var fixed = sym.fixed_value(); var right = get_rhs(node), shared = false;
var right = get_rhs(node); if (init && node.write_only === true && !right.has_side_effects(compressor)) {
var safe = fixed && fixed.is_constant();
var shared = false;
if (init
&& node.write_only === true
&& (safe || node.left === sym || right.equals(sym))
&& !right.has_side_effects(compressor)) {
initializations.add(node_def.id, right); initializations.add(node_def.id, right);
} else { } else {
right.walk(tw); right.walk(tw);
@ -8047,8 +7993,11 @@ Compressor.prototype.compress = function(node) {
if (!node.write_only || shared) { if (!node.write_only || shared) {
verify_safe_usage(node_def, sym, value_modified[node_def.id]); verify_safe_usage(node_def, sym, value_modified[node_def.id]);
} }
} else if (!safe) { } else {
verify_safe_usage(node_def, value_read[node_def.id], true); var fixed = sym.fixed_value();
if (!fixed || !fixed.is_constant()) {
verify_safe_usage(node_def, value_read[node_def.id], true);
}
} }
} }
if (track_assigns(node_def, sym) && is_lhs(sym, node) !== sym) add_assigns(node_def, sym); if (track_assigns(node_def, sym) && is_lhs(sym, node) !== sym) add_assigns(node_def, sym);
@ -8134,7 +8083,6 @@ Compressor.prototype.compress = function(node) {
} }
function trim_destructured(node, value, process, drop, root) { function trim_destructured(node, value, process, drop, root) {
var unwind = true;
var trimmer = new TreeTransformer(function(node) { var trimmer = new TreeTransformer(function(node) {
if (node instanceof AST_DefaultValue) { if (node instanceof AST_DefaultValue) {
if (!(compressor.option("default_values") && value && value.is_defined(compressor))) { if (!(compressor.option("default_values") && value && value.is_defined(compressor))) {
@ -8152,27 +8100,21 @@ Compressor.prototype.compress = function(node) {
} }
if (node instanceof AST_DestructuredArray) { if (node instanceof AST_DestructuredArray) {
var save_drop = drop; var save_drop = drop;
var save_unwind = unwind;
var save_value = value; var save_value = value;
if (value instanceof AST_SymbolRef) { if (value instanceof AST_SymbolRef) {
drop = false; drop = false;
value = value.fixed_value(); value = value.fixed_value();
} }
var last_side_effects, native, values; var native, values;
if (value instanceof AST_Array) { if (value instanceof AST_Array) {
native = true; native = true;
values = value.elements; values = value.elements;
if (save_unwind) for (last_side_effects = values.length; --last_side_effects >= 0;) {
if (values[last_side_effects].has_side_effects(compressor)) break;
}
} else { } else {
native = value && value.is_string(compressor); native = value && value.is_string(compressor);
values = false; values = false;
last_side_effects = node.elements.length;
} }
var elements = [], newValues = drop && [], pos = 0; var elements = [], newValues = drop && [], pos = 0;
node.elements.forEach(function(element, index) { node.elements.forEach(function(element, index) {
if (save_unwind) unwind = index >= last_side_effects;
value = values && values[index]; value = values && values[index];
if (value instanceof AST_Hole) { if (value instanceof AST_Hole) {
value = null; value = null;
@ -8215,7 +8157,6 @@ Compressor.prototype.compress = function(node) {
} }
} }
value = save_value; value = save_value;
unwind = save_unwind;
drop = save_drop; drop = save_drop;
if (values && newValues) { if (values && newValues) {
fill_holes(value, newValues); fill_holes(value, newValues);
@ -8224,34 +8165,22 @@ Compressor.prototype.compress = function(node) {
} }
if (!native) { if (!native) {
elements.length = node.elements.length; elements.length = node.elements.length;
} else if (!node.rest) SHORTHAND: switch (elements.length) { } else if (!node.rest) switch (elements.length) {
case 0: case 0:
if (node === root) break; if (node === root) break;
if (drop) value = value.drop_side_effect_free(compressor); if (drop) value = value.drop_side_effect_free(compressor);
return null; return null;
default: case 1:
if (!drop) break; if (!drop) break;
if (!unwind) break;
if (node === root) break; if (node === root) break;
var pos = elements.length, sym; var sym = elements[0];
while (--pos >= 0) {
var element = elements[pos];
if (element) {
sym = element;
break;
}
}
if (pos < 0) break;
for (var i = pos; --i >= 0;) {
if (elements[i]) break SHORTHAND;
}
if (sym.has_side_effects(compressor)) break; if (sym.has_side_effects(compressor)) break;
if (value.has_side_effects(compressor) && sym.match_symbol(function(node) { if (value.has_side_effects(compressor) && sym.match_symbol(function(node) {
return node instanceof AST_PropAccess; return node instanceof AST_PropAccess;
})) break; })) break;
value = make_node(AST_Sub, node, { value = make_node(AST_Sub, node, {
expression: value, expression: value,
property: make_node(AST_Number, node, { value: pos }), property: make_node(AST_Number, node, { value: 0 }),
}); });
return sym; return sym;
} }
@ -8261,19 +8190,16 @@ Compressor.prototype.compress = function(node) {
} }
if (node instanceof AST_DestructuredObject) { if (node instanceof AST_DestructuredObject) {
var save_drop = drop; var save_drop = drop;
var save_unwind = unwind;
var save_value = value; var save_value = value;
if (value instanceof AST_SymbolRef) { if (value instanceof AST_SymbolRef) {
drop = false; drop = false;
value = value.fixed_value(); value = value.fixed_value();
} }
var last_side_effects, prop_keys, prop_map, values; var prop_keys, prop_map, values;
if (value instanceof AST_Object) { if (value instanceof AST_Object) {
last_side_effects = -1;
prop_keys = []; prop_keys = [];
prop_map = new Dictionary(); prop_map = new Dictionary();
values = value.properties.map(function(prop, index) { values = value.properties.map(function(prop, index) {
if (save_unwind && prop.has_side_effects(compressor)) last_side_effects = index;
prop = prop.clone(); prop = prop.clone();
if (prop instanceof AST_Spread) { if (prop instanceof AST_Spread) {
prop_map = false; prop_map = false;
@ -8289,8 +8215,6 @@ Compressor.prototype.compress = function(node) {
} }
return prop; return prop;
}); });
} else {
last_side_effects = node.properties.length;
} }
if (node.rest) { if (node.rest) {
value = false; value = false;
@ -8313,7 +8237,6 @@ Compressor.prototype.compress = function(node) {
return key; return key;
}).forEach(function(key, index) { }).forEach(function(key, index) {
var prop = node.properties[index], trimmed; var prop = node.properties[index], trimmed;
if (save_unwind) unwind = index >= last_side_effects;
if (key instanceof AST_Node) { if (key instanceof AST_Node) {
drop = false; drop = false;
value = false; value = false;
@ -8354,7 +8277,6 @@ Compressor.prototype.compress = function(node) {
} }
}); });
value = save_value; value = save_value;
unwind = save_unwind;
drop = save_drop; drop = save_drop;
if (drop_keys && prop_keys) { if (drop_keys && prop_keys) {
value = value.clone(); value = value.clone();
@ -8362,7 +8284,6 @@ Compressor.prototype.compress = function(node) {
if (prop instanceof AST_Spread) return prop; if (prop instanceof AST_Spread) return prop;
var key = prop_keys[index]; var key = prop_keys[index];
if (key instanceof AST_Node) return prop; if (key instanceof AST_Node) return prop;
if (key === "__proto__") return prop;
if (drop_keys.has(key)) { if (drop_keys.has(key)) {
var mapped = drop_keys.get(key); var mapped = drop_keys.get(key);
if (!mapped) return prop; if (!mapped) return prop;
@ -8389,7 +8310,6 @@ Compressor.prototype.compress = function(node) {
return null; return null;
case 1: case 1:
if (!drop) break; if (!drop) break;
if (!unwind) break;
if (node === root) break; if (node === root) break;
var prop = properties[0]; var prop = properties[0];
if (prop.key instanceof AST_Node) break; if (prop.key instanceof AST_Node) break;
@ -8397,10 +8317,7 @@ Compressor.prototype.compress = function(node) {
if (value.has_side_effects(compressor) && prop.value.match_symbol(function(node) { if (value.has_side_effects(compressor) && prop.value.match_symbol(function(node) {
return node instanceof AST_PropAccess; return node instanceof AST_PropAccess;
})) break; })) break;
value = is_identifier_string(prop.key) ? make_node(AST_Dot, node, { value = make_node(AST_Sub, node, {
expression: value,
property: prop.key,
}) : make_node(AST_Sub, node, {
expression: value, expression: value,
property: make_node_from_constant(prop.key, prop), property: make_node_from_constant(prop.key, prop),
}); });
@ -8517,8 +8434,7 @@ Compressor.prototype.compress = function(node) {
&& self.find_variable(sym.name) === sym.definition(); && self.find_variable(sym.name) === sym.definition();
})) return node; })) return node;
node.definitions.forEach(function(defn) { node.definitions.forEach(function(defn) {
var name = defn.name.name; vars.set(defn.name.name, defn);
if (!vars.has(name)) vars.set(name, defn);
}); });
var seq = node.to_assignments(); var seq = node.to_assignments();
if (p instanceof AST_ForEnumeration && p.init === node) { if (p instanceof AST_ForEnumeration && p.init === node) {
@ -8545,14 +8461,13 @@ Compressor.prototype.compress = function(node) {
return !ref.in_arg; return !ref.in_arg;
})) vars.del(argname.name); })) vars.del(argname.name);
}); });
vars.each(function(defn) { vars.each(function(defn, name) {
var name = defn.name;
defn = defn.clone(); defn = defn.clone();
defn.name = name.clone(); defn.name = defn.name.clone();
defn.value = null; defn.value = null;
defns.push(defn); defns.push(defn);
var orig = name.definition().orig; vars.set(name, defn);
orig.splice(orig.indexOf(name), 0, defn.name); defn.name.definition().orig.unshift(defn.name);
}); });
if (defns.length > 0) hoisted.push(make_node(AST_Var, self, { definitions: defns })); if (defns.length > 0) hoisted.push(make_node(AST_Var, self, { definitions: defns }));
} }
@ -10383,9 +10298,10 @@ Compressor.prototype.compress = function(node) {
} }
}); });
def.references.push(name); def.references.push(name);
def.assignments++;
} }
def.assignments++;
def.eliminated++; def.eliminated++;
def.single_use = false;
return a; return a;
}, []); }, []);
if (assignments.length == 0) return null; if (assignments.length == 0) return null;
@ -11008,11 +10924,9 @@ Compressor.prototype.compress = function(node) {
&& (value = can_flatten_body(stat))) { && (value = can_flatten_body(stat))) {
var replacing = exp === fn || def.single_use && def.references.length - def.replaced == 1; var replacing = exp === fn || def.single_use && def.references.length - def.replaced == 1;
if (can_substitute_directly()) { if (can_substitute_directly()) {
self._optimized = true;
var retValue = value.optimize(compressor).clone(true);
var args = self.args.slice(); var args = self.args.slice();
var refs = []; var refs = [];
retValue = retValue.transform(new TreeTransformer(function(node) { var retValue = value.clone(true).transform(new TreeTransformer(function(node) {
if (node instanceof AST_SymbolRef) { if (node instanceof AST_SymbolRef) {
var def = node.definition(); var def = node.definition();
if (fn.variables.get(node.name) !== def) { if (fn.variables.get(node.name) !== def) {
@ -11244,10 +11158,6 @@ Compressor.prototype.compress = function(node) {
return; return;
} }
if (node instanceof AST_Class) return abort = true; if (node instanceof AST_Class) return abort = true;
if (node instanceof AST_Destructured) {
side_effects = true;
return;
}
if (node instanceof AST_Scope) return abort = true; if (node instanceof AST_Scope) return abort = true;
if (avoid && node instanceof AST_Symbol && avoid[node.name]) return abort = true; if (avoid && node instanceof AST_Symbol && avoid[node.name]) return abort = true;
if (node instanceof AST_SymbolRef) { if (node instanceof AST_SymbolRef) {
@ -13035,14 +12945,16 @@ Compressor.prototype.compress = function(node) {
if (compressor.option("dead_code")) { if (compressor.option("dead_code")) {
if (self.left instanceof AST_PropAccess) { if (self.left instanceof AST_PropAccess) {
if (self.operator == "=") { if (self.operator == "=") {
var exp = self.left.expression; if (self.redundant) {
if (self.left.equals(self.right)) { var exprs = [ self.left.expression ];
var defined = exp.defined; if (self.left instanceof AST_Sub) exprs.push(self.left.property);
exp.defined = false; exprs.push(self.right);
var drop_lhs = !self.left.has_side_effects(compressor); return make_sequence(self, exprs).optimize(compressor);
exp.defined = defined;
if (drop_lhs) return self.right;
} }
if (self.left.equals(self.right) && !self.left.has_side_effects(compressor)) {
return self.right;
}
var exp = self.left.expression;
if (exp instanceof AST_Lambda if (exp instanceof AST_Lambda
|| !compressor.has_directive("use strict") || !compressor.has_directive("use strict")
&& exp instanceof AST_Constant && exp instanceof AST_Constant
@ -14250,8 +14162,7 @@ Compressor.prototype.compress = function(node) {
stat.walk(new TreeWalker(function(node) { stat.walk(new TreeWalker(function(node) {
if (abort) return true; if (abort) return true;
if (node instanceof AST_Try) { if (node instanceof AST_Try) {
if (!node.bfinally) return; if (node.bfinally && all(node.body, function(stat) {
if (all(node.body, function(stat) {
stat.walk(find_return); stat.walk(find_return);
return !abort; return !abort;
}) && node.bcatch) node.bcatch.walk(find_return); }) && node.bcatch) node.bcatch.walk(find_return);

View File

@ -1312,7 +1312,7 @@ issue_5653: {
} }
expect: { expect: {
console.log((a => { console.log((a => {
return +{}; return console, +{};
})()); })());
} }
expect_stdout: "NaN" expect_stdout: "NaN"

View File

@ -4996,7 +4996,7 @@ cascade_forin: {
] ]
} }
unsafe_builtin_1: { unsafe_builtin: {
options = { options = {
collapse_vars: true, collapse_vars: true,
pure_getters: "strict", pure_getters: "strict",
@ -5020,46 +5020,6 @@ unsafe_builtin_1: {
expect_stdout: "1 4" expect_stdout: "1 4"
} }
unsafe_builtin_2: {
options = {
collapse_vars: true,
toplevel: true,
unsafe: true,
unused: true,
}
input: {
A = "PASS";
var a = A;
console.log(a);
}
expect: {
console.log(A = "PASS");
}
expect_stdout: "PASS"
}
unsafe_builtin_3: {
options = {
collapse_vars: true,
unsafe: true,
unused: true,
}
input: {
A = "PASS";
(function() {
var a = A;
console.log(a);
})();
}
expect: {
A = "PASS";
(function() {
console.log(A);
})();
}
expect_stdout: "PASS"
}
return_1: { return_1: {
options = { options = {
collapse_vars: true, collapse_vars: true,
@ -7390,39 +7350,30 @@ substitution_assign: {
b = 1 + (b = a); b = 1 + (b = a);
console.log(a, b); console.log(a, b);
} }
function f4(a, b) {
b = 1 + (a = b);
console.log(a, b);
}
f1(42, "foo"); f1(42, "foo");
f2(42, "foo"); f2(42, "foo");
f3(42, "foo"); f3(42, "foo");
f4("bar", 41);
} }
expect: { expect: {
function f1(a, b) { function f1(a, b) {
console.log(f1 = a, a); console.log(f1 = a, a);
} }
function f2(a, b) { function f2(a, b) {
console.log(a = 1 + (b = a), b); a = 1 + (b = a);
console.log(a, b);
} }
function f3(a, b) { function f3(a, b) {
console.log(a, b = 1 + (b = a)); b = 1 + (b = a);
}
function f4(a, b) {
b = 1 + (a = b);
console.log(a, b); console.log(a, b);
} }
f1(42, "foo"); f1(42, "foo");
f2(42, "foo"); f2(42, "foo");
f3(42, "foo"); f3(42, "foo");
f4("bar", 41);
} }
expect_stdout: [ expect_stdout: [
"42 42", "42 42",
"43 42", "43 42",
"42 43", "42 43",
"41 42",
] ]
} }
@ -10333,27 +10284,3 @@ issue_1666_undefined_strict: {
} }
expect_stdout: true expect_stdout: true
} }
issue_5869: {
options = {
collapse_vars: true,
evaluate: true,
pure_getters: "strict",
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a, b, log = console.log;
log();
a.p = 0;
b = a;
log(b);
}
expect: {
var a, log = console.log;
log();
log(void (a.p = 0));
}
expect_stdout: TypeError("Cannot set properties of undefined")
}

View File

@ -2293,7 +2293,7 @@ issue_5340_3: {
} }
expect: { expect: {
var a; var a;
(function() {})(a = true.p); (function() {})(a = true["p"]);
console.log(a); console.log(a);
} }
expect_stdout: "undefined" expect_stdout: "undefined"
@ -3107,31 +3107,3 @@ issue_5774: {
expect_stdout: "PASS" expect_stdout: "PASS"
node_version: ">=6" node_version: ">=6"
} }
issue_5863: {
options = {
collapse_vars: true,
hoist_vars: true,
}
input: {
console.log(typeof function f(a = function() {
f = 42;
return f;
}()) {
var f;
var f;
return a;
}());
}
expect: {
console.log(typeof function f(a = function() {
f = 42;
return f;
}()) {
var f;
return a;
}());
}
expect_stdout: "function"
node_version: ">=6"
}

View File

@ -1339,7 +1339,7 @@ maintain_position_var: {
} }
expect: { expect: {
A = "FAIL"; A = "FAIL";
var b = [ A ][1]; var [ , b ] = [ A ];
console.log(b || "PASS"); console.log(b || "PASS");
} }
expect_stdout: "PASS" expect_stdout: "PASS"
@ -1382,7 +1382,7 @@ side_effects_object: {
} }
} }
expect: { expect: {
var a = null, c = (console, 42..c); var a = null, c = (console, 42["c"]);
try { try {
c[a = "PASS"]; c[a = "PASS"];
} catch (e) { } catch (e) {
@ -1684,7 +1684,7 @@ singleton_1: {
expect: { expect: {
var b, a = "P"[0], o = {}; var b, a = "P"[0], o = {};
o.p = [ "FAIL"["1"] ][0]; o.p = [ "FAIL"["1"] ][0];
o.q = { foo: "S"[0] }.foo; o.q = { foo: "S"[0] }["foo"];
[ b = "S" ] = []; [ b = "S" ] = [];
console.log(a + o.p + o.q + b); console.log(a + o.p + o.q + b);
} }
@ -3886,358 +3886,3 @@ issue_5651: {
expect_stdout: true expect_stdout: true
node_version: ">=6" node_version: ">=6"
} }
issue_5843_1: {
options = {
unused: true,
}
input: {
var { p: a } = {
__proto__: {
p: "PASS",
},
};
console.log(a);
}
expect: {
var a = {
__proto__: {
p: "PASS",
},
}.p;
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5843_2: {
options = {
side_effects: true,
unused: true,
}
input: {
var a;
({ p: a } = {
__proto__: {
p: "PASS",
},
});
console.log(a);
}
expect: {
var a;
a = {
__proto__: {
p: "PASS",
},
}.p;
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5844: {
options = {
inline: true,
}
input: {
try {
(function(a) {
[ a.p ] = 42;
})(console.log("PASS"));
} catch (e) {}
}
expect: {
try {
(function(a) {
[ a.p ] = 42;
})(console.log("PASS"));
} catch (e) {}
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5854_1: {
options = {
collapse_vars: true,
}
input: {
console.log(function(a) {
var b = a;
a++;
[ b[0] ] = [ "foo" ];
return a;
}([]) ? "PASS" : "FAIL");
}
expect: {
console.log(function(a) {
var b = a;
a++;
[ b[0] ] = [ "foo" ];
return a;
}([]) ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5854_2: {
options = {
collapse_vars: true,
}
input: {
console.log(function(a) {
var b = a;
a++;
({ p: b[0] } = { p: "foo" });
return a;
}([]) ? "PASS" : "FAIL");
}
expect: {
console.log(function(a) {
var b = a;
a++;
({ p: b[0] } = { p: "foo" });
return a;
}([]) ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5866_1: {
options = {
unused: true,
}
input: {
var a = {};
var { p: { q: b } } = {
p: a,
r: a.q = "PASS",
};
console.log(b);
}
expect: {
var a = {};
var { q: b } = {
p: a,
r: a.q = "PASS",
}.p;
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5866_2: {
options = {
side_effects: true,
unused: true,
}
input: {
var a = {}, b;
({ p: { q: b } } = {
p: a,
r: a.q = "PASS",
});
console.log(b);
}
expect: {
var b, a = {};
({ q: b } = {
p: a,
r: a.q = "PASS",
}.p);
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5866_3: {
options = {
unused: true,
}
input: {
var a = {};
var [ { p: b } ] = [ a, a.p = "PASS" ];
console.log(b);
}
expect: {
var a = {};
var { p: b } = [ a, a.p = "PASS" ][0];
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5866_4: {
options = {
side_effects: true,
unused: true,
}
input: {
var a = {}, b;
[ { p: b } ] = [ a, a.p = "PASS" ];
console.log(b);
}
expect: {
var b, a = {};
({ p: b } = [ a, a.p = "PASS" ][0]);
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5866_5: {
options = {
unused: true,
}
input: {
var a = [];
var [ [ b ] ] = [ a, a[0] = "PASS" ];
console.log(b);
}
expect: {
var a = [];
var [ b ] = [ a, a[0] = "PASS" ][0];
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5866_6: {
options = {
side_effects: true,
unused: true,
}
input: {
var a = [], b;
[ [ b ] ] = [ a, a[0] = "PASS" ];
console.log(b);
}
expect: {
var b, a = [];
[ b ] = [ a, a[0] = "PASS" ][0];
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5866_7: {
options = {
unused: true,
}
input: {
var a = {};
var [ { p: b }, c ] = [ a, a.p = {} ];
console.log(b === c ? "PASS" : "FAIL");
}
expect: {
var a = {};
var [ { p: b }, c ] = [ a, a.p = {} ];
console.log(b === c ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5866_8: {
options = {
side_effects: true,
unused: true,
}
input: {
var a = {}, b, c;
[ { p: b }, c ] = [ a, a.p = {} ];
console.log(b === c ? "PASS" : "FAIL");
}
expect: {
var b, c, a = {};
[ { p: b }, c ] = [ a, a.p = {} ];
console.log(b === c ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5866_9: {
options = {
unused: true,
}
input: {
var a = {};
var [ b, { p: c } ] = [ a.p = {}, a ];
console.log(b === c ? "PASS" : "FAIL");
}
expect: {
var a = {};
var [ b, c ] = [ a.p = {}, a.p ];
console.log(b === c ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5866_10: {
options = {
side_effects: true,
unused: true,
}
input: {
var a = {}, b, c;
[ b, { p: c } ] = [ a.p = {}, a ];
console.log(b === c ? "PASS" : "FAIL");
}
expect: {
var b, c, a = {};
[ b, c ] = [ a.p = {}, a.p ];
console.log(b === c ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5866_11: {
options = {
unused: true,
}
input: {
var a = {};
var { p: { q: b } } = { p: a = { q: {} } };
console.log(a.q === b ? "PASS" : "FAIL");
}
expect: {
var a = {};
var b = { p: (a = { q: {} }).q }.p;
console.log(a.q === b ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_5866_12: {
options = {
side_effects: true,
unused: true,
}
input: {
var a = {}, b;
({ p: { q: b } } = { p: a = { q: {} } });
console.log(a.q === b ? "PASS" : "FAIL");
}
expect: {
var b, a = {};
b = { p: (a = { q: {} }).q }.p;
console.log(a.q === b ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}

View File

@ -260,7 +260,7 @@ hoist_exports_2: {
} }
} }
expect: { expect: {
let e, a = 42..foo; let e, a = 42["foo"];
function f(t, { [e]: o }) { function f(t, { [e]: o }) {
t(o, f); t(o, f);
} }

View File

@ -8817,157 +8817,3 @@ issue_5766_2: {
} }
expect_stdout: "function" expect_stdout: "function"
} }
issue_5841_1: {
options = {
conditionals: true,
evaluate: true,
inline: true,
join_vars: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
var a = 42;
(function() {
f();
var b = f();
function f() {
if (console && a)
g && g();
}
function g() {
var c;
for (;console.log("foo"););
(function h(d) {
d && d.p;
})();
}
})();
}
expect: {
var a = 42;
(function() {
f();
f();
function f() {
{
if (console && a) {
for (;console.log("foo"););
return;
}
return;
}
}
})();
}
expect_stdout: [
"foo",
"foo",
]
}
issue_5841_2: {
options = {
conditionals: true,
evaluate: true,
if_return: true,
inline: true,
join_vars: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
var a = 42;
(function() {
f();
var b = f();
function f() {
if (console && a)
g && g();
}
function g() {
var c;
for (;console.log("foo"););
(function h(d) {
d && d.p;
})();
}
})();
}
expect: {
var a = 42;
(function() {
f();
f();
function f() {
if (console && a)
for (;console.log("foo"););
}
})();
}
expect_stdout: [
"foo",
"foo",
]
}
issue_5851_1: {
options = {
inline: true,
reduce_vars: true,
toplevel: true,
}
input: {
console.log("PASS") && f();
function f() {
return f();
}
f;
}
expect: {
console.log("PASS") && f();
function f() {
return f();
}
f;
}
expect_stdout: "PASS"
}
issue_5851_2: {
options = {
conditionals: true,
inline: true,
passes: 2,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = f();
f();
function f() {
if (console.log("foo"))
console && f();
}
}
expect: {
f();
f();
function f() {
console.log("foo") && console && f();
}
}
expect_stdout: [
"foo",
"foo",
]
}

View File

@ -228,7 +228,6 @@ issue_4489: {
evaluate: true, evaluate: true,
hoist_vars: true, hoist_vars: true,
reduce_vars: true, reduce_vars: true,
sequences: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
} }
@ -364,7 +363,6 @@ issue_4893_1: {
evaluate: true, evaluate: true,
hoist_vars: true, hoist_vars: true,
reduce_vars: true, reduce_vars: true,
side_effects: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
} }
@ -385,8 +383,9 @@ issue_4893_1: {
} }
expect: { expect: {
try{ try{
(function() { (function f() {
null.p += 42; null.p += 42;
f;
})(); })();
} catch (e) { } catch (e) {
console.log("PASS"); console.log("PASS");
@ -423,7 +422,9 @@ issue_4893_2: {
expect: { expect: {
try{ try{
(function() { (function() {
null.p += 42; var a;
a = null;
a.p += 42;
})(); })();
} catch (e) { } catch (e) {
console.log("PASS"); console.log("PASS");
@ -609,7 +610,6 @@ issue_5411_2: {
evaluate: true, evaluate: true,
hoist_vars: true, hoist_vars: true,
reduce_vars: true, reduce_vars: true,
sequences: true,
toplevel: true, toplevel: true,
unused: true, unused: true,
} }
@ -622,9 +622,9 @@ issue_5411_2: {
} }
expect: { expect: {
var b, c; var b, c;
b++, b++;
b = "PASS", b = "PASS",
c, c;
console.log(b); console.log(b);
} }
expect_stdout: "PASS" expect_stdout: "PASS"

View File

@ -26,7 +26,7 @@ record_update: {
currying: { currying: {
options = { options = {
inline: true, inline: true,
passes: 3, passes: 2,
pure_getters: "strict", pure_getters: "strict",
reduce_funcs: true, reduce_funcs: true,
reduce_vars: true, reduce_vars: true,

View File

@ -23,7 +23,7 @@ join_array_assignments_1: {
} }
input: { input: {
console.log(function () { console.log(function () {
var a = [ "foo", , "bar" ]; var a = ["foo", , "bar"];
a[1] = "baz"; a[1] = "baz";
a[7] = "moo"; a[7] = "moo";
a[0] = "moz"; a[0] = "moz";
@ -32,7 +32,7 @@ join_array_assignments_1: {
} }
expect: { expect: {
console.log(function () { console.log(function () {
var a = [ "moz", "baz", "bar", , , , , "moo" ]; var a = [("foo", "moz"), "baz", "bar", , , , , "moo"];
return a; return a;
}().join()); }().join());
} }
@ -46,7 +46,7 @@ join_array_assignments_2: {
} }
input: { input: {
console.log(function () { console.log(function () {
var a = [ "foo" ]; var a = ["foo"];
a[1] = "bar"; a[1] = "bar";
a[7] = "baz"; a[7] = "baz";
a[2] = "moo"; a[2] = "moo";
@ -55,7 +55,7 @@ join_array_assignments_2: {
} }
expect: { expect: {
console.log(function () { console.log(function () {
var a = [ "foo", "bar" ]; var a = ["foo", "bar"];
a[7] = "baz"; a[7] = "baz";
a[2] = "moo"; a[2] = "moo";
return a; return a;
@ -71,7 +71,7 @@ join_array_assignments_3: {
} }
input: { input: {
console.log(function () { console.log(function () {
var a = [ "foo" ]; var a = ["foo"];
a[1] = "bar"; a[1] = "bar";
a.b = "baz"; a.b = "baz";
a[2] = "moo"; a[2] = "moo";
@ -80,7 +80,7 @@ join_array_assignments_3: {
} }
expect: { expect: {
console.log(function () { console.log(function () {
var a = [ "foo", "bar" ]; var a = ["foo", "bar"];
a.b = "baz"; a.b = "baz";
a[2] = "moo"; a[2] = "moo";
return a; return a;
@ -97,7 +97,7 @@ join_array_assignments_4: {
} }
input: { input: {
console.log(function () { console.log(function () {
var a = [ "foo" ]; var a = ["foo"];
a[0] = "bar"; a[0] = "bar";
a[1] = a; a[1] = a;
a[2] = "baz"; a[2] = "baz";
@ -106,7 +106,7 @@ join_array_assignments_4: {
} }
expect: { expect: {
console.log(function () { console.log(function () {
var a = [ "bar" ]; var a = ["bar"];
a[1] = a; a[1] = a;
a[2] = "baz"; a[2] = "baz";
return a; return a;
@ -1508,22 +1508,3 @@ issue_5831: {
} }
expect_stdout: "PASS" expect_stdout: "PASS"
} }
issue_5849: {
options = {
evaluate: true,
join_vars: true,
side_effects: true,
}
input: {
var a;
a = [ 42 ];
a[0] = "PASS";
console.log(a.join(""));
}
expect: {
var a, a = [ "PASS" ];
console.log(a.join(""));
}
expect_stdout: "PASS"
}

View File

@ -617,33 +617,3 @@ issue_5292_sub_pure_getters_strict: {
] ]
node_version: ">=14" node_version: ">=14"
} }
issue_5856: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
try {
var a;
a?.p;
a.q;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect: {
try {
var a;
a?.p;
a.q;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
node_version: ">=14"
}

View File

@ -1687,31 +1687,3 @@ issue_4939: {
} }
expect_stdout: "PASS" expect_stdout: "PASS"
} }
issue_5856: {
options = {
pure_getters: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
var a = [ "FAIL", "PASS" ];
(function(b) {
var c = b[0];
b[0] = b[1];
b[1] = c;
})(a);
console.log(a[0]);
}
expect: {
var a = [ "FAIL", "PASS" ];
(function(b) {
var c = b[0];
b[0] = b[1];
b[1] = c;
})(a);
console.log(a[0]);
}
expect_stdout: "PASS"
}

View File

@ -724,246 +724,3 @@ retain_instanceof: {
} }
expect_stdout: "PASS" expect_stdout: "PASS"
} }
drop_access: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
var o = {};
o.p;
try {
(function() {
o.q;
})();
console.log("PASS");
} catch (e) {
console.log("FAIL");
}
}
expect: {
var o = {};
o.p;
try {
console.log("PASS");
} catch (e) {
console.log("FAIL");
}
}
expect_stdout: "PASS"
}
keep_access: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
var o = {};
o.p;
o = null;
try {
(function() {
o.q;
})();
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect: {
var o = {};
o.p;
o = null;
try {
(function() {
o.q;
})();
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}
keep_access_after_call: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
var o = {};
o.p;
o.q;
f();
try {
o.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
function f() {
o = null;
}
}
expect: {
var o = {};
o.p;
f();
try {
o.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
function f() {
o = null;
}
}
expect_stdout: "PASS"
}
issue_5860_drop_1: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
var a = {};
a.p;
var a;
a.q;
console.log("PASS");
}
expect: {
var a = {};
a.p;
var a;
console.log("PASS");
}
expect_stdout: "PASS"
}
issue_5860_drop_2: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
a = {};
a.p;
var a;
a.q;
console.log("PASS");
}
expect: {
a = {};
a.p;
var a;
console.log("PASS");
}
expect_stdout: "PASS"
}
issue_5860_keep_1: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
var a = {};
a.p;
a.q;
var a = null;
try {
a.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect: {
var a = {};
a.p;
var a = null;
try {
a.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}
issue_5860_keep_2: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
a = {};
a.p;
a.q;
var a = null;
try {
a.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect: {
a = {};
a.p;
var a = null;
try {
a.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}
issue_5860_keep_3: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
}
input: {
var a = {};
a.p;
a.q;
a = null;
try {
a.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect: {
var a = {};
a.p;
a = null;
try {
a.r;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
}
expect_stdout: "PASS"
}

View File

@ -1253,24 +1253,3 @@ issue_5602: {
] ]
node_version: ">=6" node_version: ">=6"
} }
issue_5850: {
options = {
evaluate: true,
join_vars: true,
unused: true,
}
input: {
var a = [ ..."FAIL" ];
a[0] = "P";
a[2] = a[3] = "S";
console.log(a.join(""));
}
expect: {
var a = [ ..."FAIL" ];
a[0] = "P";
a[2] = a[3] = "S";
console.log(a.join(""));
}
node_version: ">=6"
}

View File

@ -1386,7 +1386,7 @@ issue_5076_1: {
expect: { expect: {
var a; var a;
console.log("PASS"), console.log("PASS"),
a = 42..a; a = 42["a"];
} }
expect_stdout: "PASS" expect_stdout: "PASS"
node_version: ">=6" node_version: ">=6"
@ -2207,43 +2207,3 @@ issue_5754: {
] ]
node_version: ">=10" node_version: ">=10"
} }
issue_5842: {
options = {
inline: true,
}
input: {
var a = "FAIL";
(async function*() {
(function() {
try {
try {
return console;
} finally {
a = "PASS";
}
} catch (e) {}
FAIL;
})();
})().next();
console.log(a);
}
expect: {
var a = "FAIL";
(async function*() {
(function() {
try {
try {
return console;
} finally {
a = "PASS";
}
} catch (e) {}
FAIL;
})();
})().next();
console.log(a);
}
expect_stdout: "PASS"
node_version: ">=10"
}