@@ -674,6 +674,16 @@ Compressor.prototype.compress = function(node) {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function replace_ref(ref, fixed) {
|
||||||
|
return function() {
|
||||||
|
var node = make_ref(ref, fixed);
|
||||||
|
var def = ref.definition();
|
||||||
|
def.references.push(node);
|
||||||
|
def.replaced++;
|
||||||
|
return node;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function ref_once(compressor, def) {
|
function ref_once(compressor, def) {
|
||||||
return compressor.option("unused")
|
return compressor.option("unused")
|
||||||
&& !def.scope.pinned()
|
&& !def.scope.pinned()
|
||||||
@@ -954,6 +964,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
};
|
};
|
||||||
left.fixed.assigns = !fixed || !fixed.assigns ? [] : fixed.assigns.slice();
|
left.fixed.assigns = !fixed || !fixed.assigns ? [] : fixed.assigns.slice();
|
||||||
left.fixed.assigns.push(node);
|
left.fixed.assigns.push(node);
|
||||||
|
left.fixed.to_binary = replace_ref(left, fixed);
|
||||||
} else {
|
} else {
|
||||||
left.walk(tw);
|
left.walk(tw);
|
||||||
ld.fixed = false;
|
ld.fixed = false;
|
||||||
@@ -1397,7 +1408,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
operator: node.operator.slice(0, -1),
|
operator: node.operator.slice(0, -1),
|
||||||
left: make_node(AST_UnaryPrefix, node, {
|
left: make_node(AST_UnaryPrefix, node, {
|
||||||
operator: "+",
|
operator: "+",
|
||||||
expression: make_ref(exp, fixed)
|
expression: make_ref(exp, fixed),
|
||||||
}),
|
}),
|
||||||
right: make_node(AST_Number, node, { value: 1 }),
|
right: make_node(AST_Number, node, { value: 1 }),
|
||||||
});
|
});
|
||||||
@@ -1414,6 +1425,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
exp.fixed.assigns = fixed && fixed.assigns;
|
exp.fixed.assigns = fixed && fixed.assigns;
|
||||||
|
exp.fixed.to_prefix = replace_ref(exp, d.fixed);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
exp.walk(tw);
|
exp.walk(tw);
|
||||||
@@ -1960,6 +1972,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
col: node.start.col,
|
col: node.start.col,
|
||||||
});
|
});
|
||||||
can_replace = false;
|
can_replace = false;
|
||||||
|
lvalues = get_lvalues(lhs);
|
||||||
node.right.transform(scanner);
|
node.right.transform(scanner);
|
||||||
clear_write_only(candidate);
|
clear_write_only(candidate);
|
||||||
var folded;
|
var folded;
|
||||||
@@ -1967,10 +1980,9 @@ Compressor.prototype.compress = function(node) {
|
|||||||
folded = candidate;
|
folded = candidate;
|
||||||
} else {
|
} else {
|
||||||
abort = true;
|
abort = true;
|
||||||
lhs.definition().fixed = false;
|
|
||||||
folded = make_node(AST_Binary, candidate, {
|
folded = make_node(AST_Binary, candidate, {
|
||||||
operator: compound,
|
operator: compound,
|
||||||
left: lhs,
|
left: lhs.fixed ? lhs.fixed.to_binary() : lhs,
|
||||||
right: rvalue,
|
right: rvalue,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2026,10 +2038,10 @@ Compressor.prototype.compress = function(node) {
|
|||||||
alternative: node,
|
alternative: node,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
if (candidate instanceof AST_UnaryPostfix) {
|
if (candidate instanceof AST_UnaryPostfix) return make_node(AST_UnaryPrefix, candidate, {
|
||||||
if (lhs instanceof AST_SymbolRef) lhs.definition().fixed = false;
|
operator: candidate.operator,
|
||||||
return make_node(AST_UnaryPrefix, candidate, candidate);
|
expression: lhs.fixed ? lhs.fixed.to_prefix() : lhs,
|
||||||
}
|
});
|
||||||
if (candidate instanceof AST_VarDef) {
|
if (candidate instanceof AST_VarDef) {
|
||||||
var def = candidate.name.definition();
|
var def = candidate.name.definition();
|
||||||
if (def.references.length - def.replaced == 1 && !compressor.exposed(def)) {
|
if (def.references.length - def.replaced == 1 && !compressor.exposed(def)) {
|
||||||
@@ -3086,16 +3098,13 @@ Compressor.prototype.compress = function(node) {
|
|||||||
var value = rvalue === rhs_value ? null : make_sequence(rhs_value, rhs_value.expressions.slice(0, -1));
|
var value = rvalue === rhs_value ? null : make_sequence(rhs_value, rhs_value.expressions.slice(0, -1));
|
||||||
var index = expr.name_index;
|
var index = expr.name_index;
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
var argname = scope.argnames[index];
|
var args, argname = scope.argnames[index];
|
||||||
if (argname instanceof AST_DefaultValue) {
|
if (argname instanceof AST_DefaultValue) {
|
||||||
|
scope.argnames[index] = argname = argname.clone();
|
||||||
argname.value = value || make_node(AST_Number, argname, { value: 0 });
|
argname.value = value || make_node(AST_Number, argname, { value: 0 });
|
||||||
argname.name.definition().fixed = false;
|
} else if ((args = compressor.parent().args)[index]) {
|
||||||
} else {
|
scope.argnames[index] = argname.clone();
|
||||||
var args = compressor.parent().args;
|
|
||||||
if (args[index]) {
|
|
||||||
args[index] = value || make_node(AST_Number, args[index], { value: 0 });
|
args[index] = value || make_node(AST_Number, args[index], { value: 0 });
|
||||||
argname.definition().fixed = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -6677,7 +6686,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
&& indexOf_assign(node.expression.definition(), node) < 0) {
|
&& indexOf_assign(node.expression.definition(), node) < 0) {
|
||||||
return make_node(AST_UnaryPrefix, node, {
|
return make_node(AST_UnaryPrefix, node, {
|
||||||
operator: "+",
|
operator: "+",
|
||||||
expression: node.expression
|
expression: node.expression,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11946,22 +11955,29 @@ Compressor.prototype.compress = function(node) {
|
|||||||
}
|
}
|
||||||
if (compressor.option("assignments")) {
|
if (compressor.option("assignments")) {
|
||||||
if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary) {
|
if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary) {
|
||||||
|
var ref;
|
||||||
// x = expr1 OP expr2
|
// x = expr1 OP expr2
|
||||||
if (self.right.left instanceof AST_SymbolRef
|
if ((ref = self.right.left) instanceof AST_SymbolRef
|
||||||
&& self.right.left.name == self.left.name
|
&& ref.name == self.left.name
|
||||||
&& ASSIGN_OPS[self.right.operator]) {
|
&& ASSIGN_OPS[self.right.operator]) {
|
||||||
// x = x - 2 ---> x -= 2
|
// x = x - 2 ---> x -= 2
|
||||||
|
if (self.left.fixed) self.left.fixed.to_binary = function() {
|
||||||
|
return ref;
|
||||||
|
};
|
||||||
return make_node(AST_Assign, self, {
|
return make_node(AST_Assign, self, {
|
||||||
operator: self.right.operator + "=",
|
operator: self.right.operator + "=",
|
||||||
left: self.left,
|
left: self.left,
|
||||||
right: self.right.right,
|
right: self.right.right,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (self.right.right instanceof AST_SymbolRef
|
if ((ref = self.right.right) instanceof AST_SymbolRef
|
||||||
&& self.right.right.name == self.left.name
|
&& ref.name == self.left.name
|
||||||
&& ASSIGN_OPS_COMMUTATIVE[self.right.operator]
|
&& ASSIGN_OPS_COMMUTATIVE[self.right.operator]
|
||||||
&& !self.right.left.has_side_effects(compressor)) {
|
&& !self.right.left.has_side_effects(compressor)) {
|
||||||
// x = 2 & x ---> x &= 2
|
// x = 2 & x ---> x &= 2
|
||||||
|
if (self.left.fixed) self.left.fixed.to_binary = function() {
|
||||||
|
return ref;
|
||||||
|
};
|
||||||
return make_node(AST_Assign, self, {
|
return make_node(AST_Assign, self, {
|
||||||
operator: self.right.operator + "=",
|
operator: self.right.operator + "=",
|
||||||
left: self.left,
|
left: self.left,
|
||||||
|
|||||||
@@ -3032,6 +3032,54 @@ compound_assignment_6: {
|
|||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compound_assignment_7: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FA";
|
||||||
|
a = a + "I";
|
||||||
|
a = a + "L";
|
||||||
|
if (console)
|
||||||
|
a = "PASS";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FA";
|
||||||
|
a = a + "I" + "L";
|
||||||
|
if (console)
|
||||||
|
a = "PASS";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
compound_assignment_8: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 2;
|
||||||
|
a = 3 * a;
|
||||||
|
a = 7 * a;
|
||||||
|
console || (a = "FAIL");
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 2;
|
||||||
|
a = a * 3 * 7;
|
||||||
|
console || (a = "FAIL");
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
issue_2187_1: {
|
issue_2187_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -8285,9 +8333,9 @@ issue_3884_1: {
|
|||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 100, b = 1;
|
var a = 100;
|
||||||
b <<= ++a;
|
++a;
|
||||||
console.log(a, b);
|
console.log(a, 32);
|
||||||
}
|
}
|
||||||
expect_stdout: "101 32"
|
expect_stdout: "101 32"
|
||||||
}
|
}
|
||||||
@@ -9715,9 +9763,30 @@ issue_5273: {
|
|||||||
function f(c, d) {
|
function f(c, d) {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
b = (b + a) * a,
|
b = 1100,
|
||||||
f,
|
f,
|
||||||
console.log(b);
|
console.log(b);
|
||||||
}
|
}
|
||||||
expect_stdout: "1100"
|
expect_stdout: "1100"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5276: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = A = "PASS";
|
||||||
|
a.p += null;
|
||||||
|
a.p -= 42;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = A = "PASS";
|
||||||
|
a.p = a.p + null - 42;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user