@@ -501,6 +501,23 @@ Compressor.prototype.compress = function(node) {
|
|||||||
if (parent instanceof AST_VarDef) return parent.value === node;
|
if (parent instanceof AST_VarDef) return parent.value === node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function make_ref(ref, fixed) {
|
||||||
|
var node = make_node(AST_SymbolRef, ref);
|
||||||
|
node.fixed = fixed || make_node(AST_Undefined, ref);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
function replace_ref(resolve, fixed) {
|
||||||
|
return function(node) {
|
||||||
|
var ref = resolve(node);
|
||||||
|
var node = make_ref(ref, fixed);
|
||||||
|
var def = ref.definition();
|
||||||
|
def.references.push(node);
|
||||||
|
def.replaced++;
|
||||||
|
return node;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var RE_POSITIVE_INTEGER = /^(0|[1-9][0-9]*)$/;
|
var RE_POSITIVE_INTEGER = /^(0|[1-9][0-9]*)$/;
|
||||||
(function(def) {
|
(function(def) {
|
||||||
def(AST_Node, noop);
|
def(AST_Node, noop);
|
||||||
@@ -705,22 +722,6 @@ Compressor.prototype.compress = function(node) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function make_ref(ref, fixed) {
|
|
||||||
var node = make_node(AST_SymbolRef, ref);
|
|
||||||
node.fixed = fixed || make_node(AST_Undefined, ref);
|
|
||||||
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()
|
||||||
@@ -1021,7 +1022,9 @@ Compressor.prototype.compress = function(node) {
|
|||||||
};
|
};
|
||||||
left.fixed.assigns = !fixed || !fixed.assigns ? [ ld.orig[0] ] : fixed.assigns.slice();
|
left.fixed.assigns = !fixed || !fixed.assigns ? [ ld.orig[0] ] : fixed.assigns.slice();
|
||||||
left.fixed.assigns.push(node);
|
left.fixed.assigns.push(node);
|
||||||
left.fixed.to_binary = replace_ref(left, fixed);
|
left.fixed.to_binary = replace_ref(function(node) {
|
||||||
|
return node.left;
|
||||||
|
}, fixed);
|
||||||
} else {
|
} else {
|
||||||
left.walk(tw);
|
left.walk(tw);
|
||||||
ld.fixed = false;
|
ld.fixed = false;
|
||||||
@@ -1529,7 +1532,9 @@ 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);
|
exp.fixed.to_prefix = replace_ref(function(node) {
|
||||||
|
return node.expression;
|
||||||
|
}, d.fixed);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
exp.walk(tw);
|
exp.walk(tw);
|
||||||
@@ -2156,7 +2161,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
abort = true;
|
abort = true;
|
||||||
folded = make_node(AST_Binary, candidate, {
|
folded = make_node(AST_Binary, candidate, {
|
||||||
operator: compound,
|
operator: compound,
|
||||||
left: lhs.fixed && lhs.definition().fixed ? lhs.fixed.to_binary() : lhs,
|
left: lhs.fixed && lhs.definition().fixed ? lhs.fixed.to_binary(candidate) : lhs,
|
||||||
right: rvalue,
|
right: rvalue,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2220,7 +2225,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
}
|
}
|
||||||
if (candidate instanceof AST_UnaryPostfix) return make_node(AST_UnaryPrefix, candidate, {
|
if (candidate instanceof AST_UnaryPostfix) return make_node(AST_UnaryPrefix, candidate, {
|
||||||
operator: candidate.operator,
|
operator: candidate.operator,
|
||||||
expression: lhs.fixed && lhs.definition().fixed ? lhs.fixed.to_prefix() : lhs,
|
expression: lhs.fixed && lhs.definition().fixed ? lhs.fixed.to_prefix(candidate) : lhs,
|
||||||
});
|
});
|
||||||
if (candidate instanceof AST_UnaryPrefix) {
|
if (candidate instanceof AST_UnaryPrefix) {
|
||||||
clear_write_only(candidate);
|
clear_write_only(candidate);
|
||||||
@@ -12780,34 +12785,19 @@ 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 ((ref = self.right.left) instanceof AST_SymbolRef
|
if (self.right.left instanceof AST_SymbolRef
|
||||||
&& ref.name == self.left.name
|
&& self.right.left.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 make_compound(self.right.right);
|
||||||
return ref;
|
|
||||||
};
|
|
||||||
return make_node(AST_Assign, self, {
|
|
||||||
operator: self.right.operator + "=",
|
|
||||||
left: self.left,
|
|
||||||
right: self.right.right,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if ((ref = self.right.right) instanceof AST_SymbolRef
|
if (self.right.right instanceof AST_SymbolRef
|
||||||
&& ref.name == self.left.name
|
&& self.right.right.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 make_compound(self.right.left);
|
||||||
return ref;
|
|
||||||
};
|
|
||||||
return make_node(AST_Assign, self, {
|
|
||||||
operator: self.right.operator + "=",
|
|
||||||
left: self.left,
|
|
||||||
right: self.right.left,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((self.operator == "-=" || self.operator == "+="
|
if ((self.operator == "-=" || self.operator == "+="
|
||||||
@@ -12870,6 +12860,18 @@ Compressor.prototype.compress = function(node) {
|
|||||||
return find_try(compressor, level, node, scope, may_throw, sync);
|
return find_try(compressor, level, node, scope, may_throw, sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function make_compound(rhs) {
|
||||||
|
var fixed = self.left.fixed;
|
||||||
|
if (fixed) fixed.to_binary = replace_ref(function(node) {
|
||||||
|
return node.left;
|
||||||
|
}, fixed);
|
||||||
|
return make_node(AST_Assign, self, {
|
||||||
|
operator: self.right.operator + "=",
|
||||||
|
left: self.left,
|
||||||
|
right: rhs,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function strip_assignment(def) {
|
function strip_assignment(def) {
|
||||||
if (def) def.fixed = false;
|
if (def) def.fixed = false;
|
||||||
return (self.operator != "=" ? make_node(AST_Binary, self, {
|
return (self.operator != "=" ? make_node(AST_Binary, self, {
|
||||||
|
|||||||
@@ -7927,3 +7927,138 @@ issue_5623: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5716_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
merge_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
function f() {
|
||||||
|
var b = [ c, c ], c = function() {
|
||||||
|
return b++ + (a = b);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
c = [ c, c ],
|
||||||
|
void (c = ++c);
|
||||||
|
var c;
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "NaN"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5716_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
merge_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
function f() {
|
||||||
|
var b = [ c, c ], c = function() {
|
||||||
|
return (b += 4) + (a = b += 2);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
void (c = c = (c = [ c, c ]) + 4 + 2);
|
||||||
|
var c;
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: ",42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5716_3: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
merge_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
function f() {
|
||||||
|
var b = [ c, c ], c = function() {
|
||||||
|
return (b = b + 4) + (a = b += 2);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
void (c = c = (c = [ c, c ]) + 4 + 2);
|
||||||
|
var c;
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: ",42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5716_4: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
merge_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
function f() {
|
||||||
|
var b = [ c, c ], c = function() {
|
||||||
|
return (b = true | b) + (a = b *= 42);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
void (c = c = ((c = [ c, c ]) | true) * 42);
|
||||||
|
var c;
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5716_5: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
return 0 || (a = 42 | a);
|
||||||
|
var a = function() {
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
return 0 || (a |= 42);
|
||||||
|
var a = function() {
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user