@@ -773,7 +773,7 @@ var AST_Label = DEFNODE("Label", "references", {
|
||||
}
|
||||
}, AST_Symbol);
|
||||
|
||||
var AST_SymbolRef = DEFNODE("SymbolRef", null, {
|
||||
var AST_SymbolRef = DEFNODE("SymbolRef", "fixed", {
|
||||
$documentation: "Reference to some symbol (not definition/declaration)",
|
||||
}, AST_Symbol);
|
||||
|
||||
|
||||
@@ -551,6 +551,7 @@ merge(Compressor.prototype, {
|
||||
mark_assignment_to_arguments(sym);
|
||||
return;
|
||||
}
|
||||
if (sym.fixed) delete sym.fixed;
|
||||
var d = sym.definition();
|
||||
var safe = safe_to_assign(tw, d, sym.scope, node.right);
|
||||
d.assignments++;
|
||||
@@ -560,7 +561,7 @@ merge(Compressor.prototype, {
|
||||
var value = eq ? node.right : node;
|
||||
if (is_modified(compressor, tw, node, value, 0)) return;
|
||||
if (!eq) d.chained = true;
|
||||
d.fixed = eq ? function() {
|
||||
sym.fixed = d.fixed = eq ? function() {
|
||||
return node.right;
|
||||
} : function() {
|
||||
return make_node(AST_Binary, node, {
|
||||
@@ -574,7 +575,7 @@ merge(Compressor.prototype, {
|
||||
mark(tw, d, false);
|
||||
node.right.walk(tw);
|
||||
mark(tw, d, true);
|
||||
mark_escaped(tw, d, sym.scope, node, value, 0, 1);
|
||||
if (eq) mark_escaped(tw, d, sym.scope, node, value, 0, 1);
|
||||
return true;
|
||||
});
|
||||
def(AST_Binary, function(tw) {
|
||||
@@ -730,6 +731,7 @@ merge(Compressor.prototype, {
|
||||
this.definition().fixed = false;
|
||||
});
|
||||
def(AST_SymbolRef, function(tw, descend, compressor) {
|
||||
if (this.fixed) delete this.fixed;
|
||||
var d = this.definition();
|
||||
d.references.push(this);
|
||||
if (d.references.length == 1
|
||||
@@ -797,13 +799,14 @@ merge(Compressor.prototype, {
|
||||
mark_assignment_to_arguments(exp);
|
||||
return;
|
||||
}
|
||||
if (exp.fixed) delete exp.fixed;
|
||||
var d = exp.definition();
|
||||
var safe = safe_to_assign(tw, d, exp.scope, true);
|
||||
d.assignments++;
|
||||
var fixed = d.fixed;
|
||||
if (!fixed) return;
|
||||
d.chained = true;
|
||||
d.fixed = function() {
|
||||
exp.fixed = d.fixed = function() {
|
||||
return make_node(AST_Binary, node, {
|
||||
operator: node.operator.slice(0, -1),
|
||||
left: make_node(AST_UnaryPrefix, node, {
|
||||
@@ -874,10 +877,11 @@ merge(Compressor.prototype, {
|
||||
this.walk(tw);
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("fixed_value", function() {
|
||||
AST_Symbol.DEFMETHOD("fixed_value", function(final) {
|
||||
var fixed = this.definition().fixed;
|
||||
if (!fixed || fixed instanceof AST_Node) return fixed;
|
||||
return fixed();
|
||||
if (!fixed) return fixed;
|
||||
if (!final && this.fixed) fixed = this.fixed;
|
||||
return fixed instanceof AST_Node ? fixed : fixed();
|
||||
});
|
||||
|
||||
AST_SymbolRef.DEFMETHOD("is_immutable", function() {
|
||||
@@ -3514,7 +3518,7 @@ merge(Compressor.prototype, {
|
||||
if (def.value.has_side_effects(compressor)) {
|
||||
def.value.walk(tw);
|
||||
}
|
||||
if (!node_def.chained && def.name.fixed_value() === def.value) {
|
||||
if (!node_def.chained && def.name.fixed_value(true) === def.value) {
|
||||
fixed_ids[node_def.id] = def;
|
||||
}
|
||||
}
|
||||
@@ -3785,7 +3789,7 @@ merge(Compressor.prototype, {
|
||||
if (node instanceof AST_Assign) {
|
||||
node.right.walk(tw);
|
||||
if (node.left === sym) {
|
||||
if (!node_def.chained && sym.fixed_value() === node.right) {
|
||||
if (!node_def.chained && sym.fixed_value(true) === node.right) {
|
||||
fixed_ids[node_def.id] = node;
|
||||
}
|
||||
if (!node.write_only) {
|
||||
|
||||
@@ -289,3 +289,25 @@ increment_decrement_2: {
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_3375: {
|
||||
options = {
|
||||
assignments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function(b) {
|
||||
var a = b += 1;
|
||||
--b;
|
||||
return a;
|
||||
}("object"));
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function(b) {
|
||||
var a = b += 1;
|
||||
--b;
|
||||
return a;
|
||||
}("object"));
|
||||
}
|
||||
expect_stdout: "string"
|
||||
}
|
||||
|
||||
@@ -2005,3 +2005,24 @@ issue_3233: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3375: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var b = 1;
|
||||
var a = c = [], c = --b + ("function" == typeof f && f());
|
||||
var a = c && c[a];
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var b = 1;
|
||||
var a = [], c = --b + ("function" == typeof f && f());
|
||||
a = c && c[a];
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "0 0"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user