fix corner cases in collapse_vars (#5553)

fixes #5552
This commit is contained in:
Alex Lam S.L
2022-07-09 13:50:54 +01:00
committed by GitHub
parent 0b808f6428
commit 38bd4f65d0
2 changed files with 132 additions and 29 deletions

View File

@@ -2477,24 +2477,24 @@ Compressor.prototype.compress = function(node) {
can_replace = false;
var after = stop_after;
var if_hit = stop_if_hit;
if (!all(fn.argnames, function(argname) {
if (argname instanceof AST_DefaultValue) {
argname.value.transform(scanner);
if (abort) return false;
argname = argname.name;
for (var i = 0; !abort && i < fn.argnames.length; i++) {
if (may_throw_arg(reject, fn.argnames[i], node.args[i])) abort = true;
}
if (!abort) {
if (fn.rest && may_throw_arg(reject, fn.rest, make_node(AST_Array, node, {
elements: node.args.slice(i),
}))) {
abort = true;
} else if (is_arrow(fn) && fn.value) {
fn.value.transform(scanner);
} else for (var i = 0; !abort && i < fn.body.length; i++) {
var stat = fn.body[i];
if (stat instanceof AST_Return) {
if (stat.value) stat.value.transform(scanner);
break;
}
stat.transform(scanner);
}
return !(argname instanceof AST_Destructured);
})) {
abort = true;
} else if (is_arrow(fn) && fn.value) {
fn.value.transform(scanner);
} else for (var i = 0; !abort && i < fn.body.length; i++) {
var stat = fn.body[i];
if (stat instanceof AST_Return) {
if (stat.value) stat.value.transform(scanner);
break;
}
stat.transform(scanner);
}
stop_if_hit = if_hit;
stop_after = after;
@@ -2560,28 +2560,35 @@ Compressor.prototype.compress = function(node) {
return node instanceof AST_SymbolRef
&& (lvalues.has(node.name) || read_toplevel && compressor.exposed(node.definition()));
}, true);
function reject(node) {
node.transform(scanner);
return abort;
}
}
function may_throw_destructured(node, value) {
if (!value) return !(node instanceof AST_Symbol);
function may_throw_arg(reject, node, value) {
if (node instanceof AST_DefaultValue) {
return value.has_side_effects(compressor)
|| node.value.has_side_effects(compressor)
|| may_throw_destructured(node.name, is_undefined(value) && node.value);
return reject(node.value)
|| may_throw_arg(reject, node.name, node.value)
|| !is_undefined(value) && may_throw_arg(reject, node.name, value);
}
if (!value) return !(node instanceof AST_Symbol);
if (node instanceof AST_Destructured) {
if (node.rest && may_throw_destructured(node.rest)) return true;
if (node.rest && may_throw_arg(reject, node.rest)) return true;
if (node instanceof AST_DestructuredArray) {
if (!(value instanceof AST_Array || value.is_string(compressor))) return true;
return !all(node.elements, function(element) {
return !may_throw_destructured(element);
if (value instanceof AST_Array) return !all(node.elements, function(element, index) {
return !may_throw_arg(reject, element, value[index]);
});
return value.is_string(compressor) && !all(node.elements, function(element) {
return !may_throw_arg(reject, element);
});
}
if (node instanceof AST_DestructuredObject) {
if (!value.is_defined(compressor)) return true;
return !all(node.properties, function(prop) {
if (prop instanceof AST_Node && prop.has_side_effects(compressor)) return false;
return !may_throw_destructured(prop.value);
if (prop.key instanceof AST_Node && reject(prop.key)) return false;
return !may_throw_arg(reject, prop.value);
});
}
}
@@ -2645,7 +2652,9 @@ Compressor.prototype.compress = function(node) {
args[len + i] = value;
}
if (sym instanceof AST_Destructured) {
if (!may_throw_destructured(sym, arg)) continue;
if (!may_throw_arg(function(node) {
return node.has_side_effects(compressor);
}, sym, arg)) continue;
candidates.length = 0;
break;
}
@@ -2668,6 +2677,7 @@ Compressor.prototype.compress = function(node) {
candidate.arg_index = value ? len + i : i;
candidates.unshift([ candidate ]);
}
if (fn.rest) args.push(fn.rest);
}
}