fix bugs on substituted AST_Defun (#2661)

fixes #2660
This commit is contained in:
Alex Lam S.L
2017-12-27 05:31:37 +08:00
committed by GitHub
parent 4832bc5d88
commit 3ff625de7e
2 changed files with 64 additions and 8 deletions

View File

@@ -3685,8 +3685,9 @@ merge(Compressor.prototype, {
if (compressor.option("reduce_vars") && fn instanceof AST_SymbolRef) { if (compressor.option("reduce_vars") && fn instanceof AST_SymbolRef) {
fn = fn.fixed_value(); fn = fn.fixed_value();
} }
var is_func = fn instanceof AST_Lambda;
if (compressor.option("unused") if (compressor.option("unused")
&& fn instanceof AST_Function && is_func
&& !fn.uses_arguments && !fn.uses_arguments
&& !fn.uses_eval) { && !fn.uses_eval) {
var pos = 0, last = 0; var pos = 0, last = 0;
@@ -3855,7 +3856,7 @@ merge(Compressor.prototype, {
if (func instanceof AST_SymbolRef) { if (func instanceof AST_SymbolRef) {
func = func.fixed_value(); func = func.fixed_value();
} }
if (func instanceof AST_Function && !func.contains_this()) { if (func instanceof AST_Lambda && !func.contains_this()) {
return make_sequence(this, [ return make_sequence(this, [
self.args[0], self.args[0],
make_node(AST_Call, self, { make_node(AST_Call, self, {
@@ -3925,7 +3926,7 @@ merge(Compressor.prototype, {
} }
} }
} }
var stat = fn instanceof AST_Function && fn.body[0]; var stat = is_func && fn.body[0];
if (compressor.option("inline") && stat instanceof AST_Return) { if (compressor.option("inline") && stat instanceof AST_Return) {
var value = stat.value; var value = stat.value;
if (!value || value.is_constant_expression()) { if (!value || value.is_constant_expression()) {
@@ -3933,7 +3934,7 @@ merge(Compressor.prototype, {
return make_sequence(self, args).optimize(compressor); return make_sequence(self, args).optimize(compressor);
} }
} }
if (fn instanceof AST_Function) { if (is_func) {
var def, value, scope, level = -1; var def, value, scope, level = -1;
if (compressor.option("inline") if (compressor.option("inline")
&& !fn.uses_arguments && !fn.uses_arguments
@@ -4670,11 +4671,8 @@ merge(Compressor.prototype, {
&& is_lhs(self, compressor.parent()) !== self) { && is_lhs(self, compressor.parent()) !== self) {
var d = self.definition(); var d = self.definition();
var fixed = self.fixed_value(); var fixed = self.fixed_value();
if (fixed instanceof AST_Defun) {
d.fixed = fixed = make_node(AST_Function, fixed, fixed);
}
var single_use = d.single_use; var single_use = d.single_use;
if (single_use && fixed instanceof AST_Function) { if (single_use && fixed instanceof AST_Lambda) {
if (d.scope !== self.scope if (d.scope !== self.scope
&& (!compressor.option("reduce_funcs") && (!compressor.option("reduce_funcs")
|| d.escaped == 1 || d.escaped == 1
@@ -4695,6 +4693,9 @@ merge(Compressor.prototype, {
} }
} }
if (single_use && fixed) { if (single_use && fixed) {
if (fixed instanceof AST_Defun) {
fixed = make_node(AST_Function, fixed, fixed);
}
var value; var value;
if (d.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) { if (d.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) {
value = fixed.clone(true); value = fixed.clone(true);
@@ -4705,6 +4706,7 @@ merge(Compressor.prototype, {
value.walk(new TreeWalker(function(node) { value.walk(new TreeWalker(function(node) {
if (node instanceof AST_SymbolRef && node.definition() === defun_def) { if (node instanceof AST_SymbolRef && node.definition() === defun_def) {
node.thedef = lambda_def; node.thedef = lambda_def;
lambda_def.references.push(node);
} }
})); }));
} else { } else {

View File

@@ -1434,3 +1434,57 @@ defun_lambda_same_name: {
} }
expect_stdout: "120" expect_stdout: "120"
} }
issue_2660_1: {
options = {
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = 2;
function f(b) {
return b && f() || a--;
}
f(1);
console.log(a);
}
expect: {
var a = 2;
(function f(b) {
return b && f() || a--;
})(1);
console.log(a);
}
expect_stdout: "1"
}
issue_2660_2: {
options = {
collapse_vars: true,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = 1;
function f(b) {
b && f();
--a, a.toString();
}
f();
console.log(a);
}
expect: {
var a = 1;
(function f(b) {
b && f(),
(--a).toString();
})(),
console.log(a);
}
expect_stdout: "0"
}