@@ -389,7 +389,18 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
var lhs = is_lhs(node, parent);
|
var lhs = is_lhs(node, parent);
|
||||||
if (lhs) return lhs;
|
if (lhs) return lhs;
|
||||||
|
if (level == 0 && value && value.is_constant()) return;
|
||||||
if (parent instanceof AST_Array) return is_modified(compressor, tw, parent, parent, level + 1);
|
if (parent instanceof AST_Array) return is_modified(compressor, tw, parent, parent, level + 1);
|
||||||
|
if (parent instanceof AST_Assign) switch (parent.operator) {
|
||||||
|
case "=":
|
||||||
|
return is_modified(compressor, tw, parent, value, level + 1, immutable, recursive);
|
||||||
|
case "&&=":
|
||||||
|
case "||=":
|
||||||
|
case "??=":
|
||||||
|
return is_modified(compressor, tw, parent, parent, level + 1);
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (parent instanceof AST_Binary) {
|
if (parent instanceof AST_Binary) {
|
||||||
if (!lazy_op[parent.operator]) return;
|
if (!lazy_op[parent.operator]) return;
|
||||||
return is_modified(compressor, tw, parent, parent, level + 1);
|
return is_modified(compressor, tw, parent, parent, level + 1);
|
||||||
@@ -625,7 +636,7 @@ merge(Compressor.prototype, {
|
|||||||
if (def.fixed === undefined) return declare || all(def.orig, function(sym) {
|
if (def.fixed === undefined) return declare || all(def.orig, function(sym) {
|
||||||
return !(sym instanceof AST_SymbolLet);
|
return !(sym instanceof AST_SymbolLet);
|
||||||
});
|
});
|
||||||
if (def.fixed === false) return false;
|
if (def.fixed === false || def.fixed === 0) return false;
|
||||||
var safe = tw.safe_ids[def.id];
|
var safe = tw.safe_ids[def.id];
|
||||||
if (def.safe_ids) {
|
if (def.safe_ids) {
|
||||||
def.safe_ids[def.id] = false;
|
def.safe_ids[def.id] = false;
|
||||||
@@ -973,7 +984,13 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
var d = sym.definition();
|
var d = sym.definition();
|
||||||
d.assignments++;
|
d.assignments++;
|
||||||
if (fixed && !modified && !sym.in_arg && safe_to_assign(tw, d)) {
|
if (!fixed || sym.in_arg || !safe_to_assign(tw, d)) {
|
||||||
|
walk();
|
||||||
|
d.fixed = false;
|
||||||
|
} else if (modified) {
|
||||||
|
walk();
|
||||||
|
d.fixed = 0;
|
||||||
|
} else {
|
||||||
push_ref(d, sym);
|
push_ref(d, sym);
|
||||||
mark(tw, d);
|
mark(tw, d);
|
||||||
if (left instanceof AST_Destructured
|
if (left instanceof AST_Destructured
|
||||||
@@ -984,9 +1001,6 @@ merge(Compressor.prototype, {
|
|||||||
mark_escaped(tw, d, sym.scope, node, right, 0, 1);
|
mark_escaped(tw, d, sym.scope, node, right, 0, 1);
|
||||||
sym.fixed = d.fixed = fixed;
|
sym.fixed = d.fixed = fixed;
|
||||||
sym.fixed.assigns = [ node ];
|
sym.fixed.assigns = [ node ];
|
||||||
} else {
|
|
||||||
walk();
|
|
||||||
d.fixed = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1265,7 +1279,7 @@ merge(Compressor.prototype, {
|
|||||||
if (!safe) return;
|
if (!safe) return;
|
||||||
safe.assign = true;
|
safe.assign = true;
|
||||||
});
|
});
|
||||||
if (d.fixed === false) {
|
if (d.fixed === false || d.fixed === 0) {
|
||||||
var redef = d.redefined();
|
var redef = d.redefined();
|
||||||
if (redef && cross_scope(d.scope, this.scope)) redef.single_use = false;
|
if (redef && cross_scope(d.scope, this.scope)) redef.single_use = false;
|
||||||
} else if (d.fixed === undefined || !safe_to_read(tw, d)) {
|
} else if (d.fixed === undefined || !safe_to_read(tw, d)) {
|
||||||
@@ -1290,7 +1304,7 @@ merge(Compressor.prototype, {
|
|||||||
if (d.single_use) {
|
if (d.single_use) {
|
||||||
d.single_use = "m";
|
d.single_use = "m";
|
||||||
} else {
|
} else {
|
||||||
d.fixed = false;
|
d.fixed = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (d.fixed && tw.loop_ids[d.id] !== tw.in_loop) d.cross_loop = true;
|
if (d.fixed && tw.loop_ids[d.id] !== tw.in_loop) d.cross_loop = true;
|
||||||
@@ -1475,9 +1489,14 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
AST_Symbol.DEFMETHOD("fixed_value", function() {
|
AST_Symbol.DEFMETHOD("fixed_value", function() {
|
||||||
var fixed = this.definition().fixed;
|
var fixed = this.definition().fixed;
|
||||||
if (!fixed) return fixed;
|
if (fixed) {
|
||||||
if (this.fixed) fixed = this.fixed;
|
if (this.fixed) fixed = this.fixed;
|
||||||
return fixed instanceof AST_Node ? fixed : fixed();
|
return fixed instanceof AST_Node ? fixed : fixed();
|
||||||
|
}
|
||||||
|
fixed = fixed === 0 && this.fixed;
|
||||||
|
if (!fixed) return fixed;
|
||||||
|
var value = fixed instanceof AST_Node ? fixed : fixed();
|
||||||
|
return value.is_constant() && value;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_SymbolRef.DEFMETHOD("is_immutable", function() {
|
AST_SymbolRef.DEFMETHOD("is_immutable", function() {
|
||||||
@@ -3593,11 +3612,11 @@ merge(Compressor.prototype, {
|
|||||||
if (!(node.left instanceof AST_PropAccess)) return;
|
if (!(node.left instanceof AST_PropAccess)) return;
|
||||||
var sym = node.left.expression;
|
var sym = node.left.expression;
|
||||||
if (!(sym instanceof AST_SymbolRef)) return;
|
if (!(sym instanceof AST_SymbolRef)) return;
|
||||||
if (!names[sym.name]) return;
|
if (!(sym.name in names)) return;
|
||||||
if (!node.right.is_constant_expression(scope)) return;
|
if (!node.right.is_constant_expression(scope)) return;
|
||||||
var prop = node.left.property;
|
var prop = node.left.property;
|
||||||
if (prop instanceof AST_Node) {
|
if (prop instanceof AST_Node) {
|
||||||
if (try_join(prop)) prop = node.left.property = prop.right;
|
if (try_join(prop)) prop = node.left.property = prop.right.clone();
|
||||||
prop = prop.evaluate(compressor);
|
prop = prop.evaluate(compressor);
|
||||||
}
|
}
|
||||||
if (prop instanceof AST_Node) return;
|
if (prop instanceof AST_Node) return;
|
||||||
@@ -3615,7 +3634,7 @@ merge(Compressor.prototype, {
|
|||||||
if (!all(value.properties, diff)) return;
|
if (!all(value.properties, diff)) return;
|
||||||
value.properties.push(make_node(AST_ObjectKeyVal, node, {
|
value.properties.push(make_node(AST_ObjectKeyVal, node, {
|
||||||
key: prop,
|
key: prop,
|
||||||
value: node.right
|
value: node.right,
|
||||||
}));
|
}));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -507,7 +507,7 @@ chained_assignments: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
folded_assignments: {
|
folded_assignments_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
@@ -527,6 +527,30 @@ folded_assignments: {
|
|||||||
expect_stdout: "PASS 42"
|
expect_stdout: "PASS 42"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
folded_assignments_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = {};
|
||||||
|
a[42] = "FAIL";
|
||||||
|
a[a.PASS = 42] = "PASS";
|
||||||
|
console.log(a[42], a.PASS);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
var a = {
|
||||||
|
42: "FAIL",
|
||||||
|
PASS: 42,
|
||||||
|
};
|
||||||
|
a[42] = "PASS";
|
||||||
|
console.log(a[42], a.PASS);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
}
|
||||||
|
|
||||||
inlined_assignments: {
|
inlined_assignments: {
|
||||||
options = {
|
options = {
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
@@ -550,6 +574,7 @@ typescript_enum: {
|
|||||||
rename = true
|
rename = true
|
||||||
options = {
|
options = {
|
||||||
assignments: true,
|
assignments: true,
|
||||||
|
collapse_vars: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
hoist_props: true,
|
hoist_props: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
|
|||||||
@@ -7320,6 +7320,46 @@ local_assignment_loop: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local_assignment_modified: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
(a = a || {}).p = 42;
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
(a = {}).p = 42;
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
local_definition_modified: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = a || {};
|
||||||
|
a.p = 42;
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = {};
|
||||||
|
a.p = 42;
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
issue_3957_1: {
|
issue_3957_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -7435,6 +7475,7 @@ issue_4030: {
|
|||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user