@@ -884,15 +884,12 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
if (ld && right instanceof AST_LambdaExpression) {
|
||||
walk_assign();
|
||||
if (ld.escaped.length) {
|
||||
right.walk(tw);
|
||||
} else {
|
||||
right.parent_scope.resolve().fn_defs.push(right);
|
||||
right.safe_ids = null;
|
||||
if (!node.write_only) mark_fn_def(tw, ld, right);
|
||||
}
|
||||
right.parent_scope.resolve().fn_defs.push(right);
|
||||
right.safe_ids = null;
|
||||
if (!ld.fixed || !node.write_only) mark_fn_def(tw, ld, right);
|
||||
return true;
|
||||
} else if (scan) {
|
||||
}
|
||||
if (scan) {
|
||||
right.walk(tw);
|
||||
walk_assign();
|
||||
return true;
|
||||
@@ -1397,31 +1394,38 @@ merge(Compressor.prototype, {
|
||||
var node = this;
|
||||
var value = node.value;
|
||||
if (value instanceof AST_LambdaExpression && node.name instanceof AST_SymbolDeclaration) {
|
||||
walk_defn();
|
||||
value.parent_scope.resolve().fn_defs.push(value);
|
||||
value.safe_ids = null;
|
||||
var ld = node.name.definition();
|
||||
if (!ld.fixed) mark_fn_def(tw, ld, value);
|
||||
} else if (value) {
|
||||
value.walk(tw);
|
||||
} else if (!(tw.parent() instanceof AST_Let)) {
|
||||
return;
|
||||
walk_defn();
|
||||
} else if (tw.parent() instanceof AST_Let) {
|
||||
walk_defn();
|
||||
}
|
||||
scan_declaration(tw, compressor, node.name, function() {
|
||||
return node.value || make_node(AST_Undefined, node);
|
||||
}, function(name, fixed) {
|
||||
var d = name.definition();
|
||||
if (fixed && safe_to_assign(tw, d, true)) {
|
||||
mark(tw, d);
|
||||
tw.loop_ids[d.id] = tw.in_loop;
|
||||
d.fixed = fixed;
|
||||
d.fixed.assigns = [ node ];
|
||||
if (name instanceof AST_SymbolConst && d.redefined()
|
||||
|| !(can_drop_symbol(name) || is_safe_lexical(d))) {
|
||||
d.single_use = false;
|
||||
}
|
||||
} else {
|
||||
d.fixed = false;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
|
||||
function walk_defn() {
|
||||
scan_declaration(tw, compressor, node.name, function() {
|
||||
return node.value || make_node(AST_Undefined, node);
|
||||
}, function(name, fixed) {
|
||||
var d = name.definition();
|
||||
if (fixed && safe_to_assign(tw, d, true)) {
|
||||
mark(tw, d);
|
||||
tw.loop_ids[d.id] = tw.in_loop;
|
||||
d.fixed = fixed;
|
||||
d.fixed.assigns = [ node ];
|
||||
if (name instanceof AST_SymbolConst && d.redefined()
|
||||
|| !(can_drop_symbol(name) || is_safe_lexical(d))) {
|
||||
d.single_use = false;
|
||||
}
|
||||
} else {
|
||||
d.fixed = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
def(AST_While, function(tw, descend) {
|
||||
var save_loop = tw.in_loop;
|
||||
|
||||
@@ -556,7 +556,7 @@ reduce_iife_3: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
reduce_lambda: {
|
||||
reduce_lambda_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
@@ -588,6 +588,43 @@ reduce_lambda: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
reduce_lambda_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(f, a, b) {
|
||||
f = () => {
|
||||
console.log(a, b);
|
||||
};
|
||||
a = "foo", b = 42;
|
||||
f();
|
||||
b = "bar";
|
||||
f();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(f, a, b) {
|
||||
f = () => {
|
||||
console.log("foo", b);
|
||||
};
|
||||
b = 42;
|
||||
f();
|
||||
b = "bar";
|
||||
f();
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo 42",
|
||||
"foo bar",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
single_use_recursive: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
|
||||
@@ -6413,3 +6413,125 @@ issue_5067: {
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
issue_5096_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a, b = "FAIL", c = 1;
|
||||
do {
|
||||
a && a();
|
||||
a = function() {
|
||||
b = "PASS";
|
||||
};
|
||||
} while (c--);
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var a, b = "FAIL", c = 1;
|
||||
do {
|
||||
a && a();
|
||||
a = function() {
|
||||
b = "PASS";
|
||||
};
|
||||
} while (c--);
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5096_2: {
|
||||
options = {
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a, b = "FAIL", c = 1;
|
||||
do {
|
||||
a && a();
|
||||
a = function() {
|
||||
b = "PASS";
|
||||
};
|
||||
} while (c--);
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var a, b = "FAIL", c = 1;
|
||||
do {
|
||||
a && a();
|
||||
a = function() {
|
||||
b = "PASS";
|
||||
};
|
||||
} while (c--);
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5096_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var b = "FAIL", c = 1;
|
||||
do {
|
||||
a && a();
|
||||
var a = function() {
|
||||
b = "PASS";
|
||||
};
|
||||
} while (c--);
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b = "FAIL", c = 1;
|
||||
do {
|
||||
a && a();
|
||||
var a = function() {
|
||||
b = "PASS";
|
||||
};
|
||||
} while (c--);
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5096_4: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var b = "FAIL", c = 1;
|
||||
do {
|
||||
a && a();
|
||||
var a = function() {
|
||||
b = "PASS";
|
||||
};
|
||||
} while (c--);
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b = "FAIL", c = 1;
|
||||
do {
|
||||
a && a();
|
||||
var a = function() {
|
||||
b = "PASS";
|
||||
};
|
||||
} while (c--);
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user