enhance collapse_vars (#5556)

This commit is contained in:
Alex Lam S.L
2022-07-12 16:49:43 +01:00
committed by GitHub
parent 154edf0427
commit 24443b6764

View File

@@ -1675,6 +1675,7 @@ Compressor.prototype.compress = function(node) {
if (may_throw && parent.bcatch && parent.bcatch !== node) return true; if (may_throw && parent.bcatch && parent.bcatch !== node) return true;
} }
} }
return false;
} }
var identifier_atom = makePredicate("Infinity NaN undefined"); var identifier_atom = makePredicate("Infinity NaN undefined");
@@ -1917,7 +1918,7 @@ Compressor.prototype.compress = function(node) {
var in_lambda = last_of(compressor, function(node) { var in_lambda = last_of(compressor, function(node) {
return node instanceof AST_Lambda; return node instanceof AST_Lambda;
}); });
var block_scope, in_loop, in_try, scope; var block_scope, iife_in_try, in_iife_single, in_loop, in_try, scope;
find_loop_scope_try(); find_loop_scope_try();
var changed, last_changed, max_iter = 10; var changed, last_changed, max_iter = 10;
do { do {
@@ -2490,10 +2491,10 @@ Compressor.prototype.compress = function(node) {
var after = stop_after; var after = stop_after;
var if_hit = stop_if_hit; var if_hit = stop_if_hit;
for (var i = 0; !abort && i < fn.argnames.length; i++) { for (var i = 0; !abort && i < fn.argnames.length; i++) {
if (may_throw_arg(reject, fn.argnames[i], node.args[i])) abort = true; if (arg_may_throw(reject, fn.argnames[i], node.args[i])) abort = true;
} }
if (!abort) { if (!abort) {
if (fn.rest && may_throw_arg(reject, fn.rest, make_node(AST_Array, node, { if (fn.rest && arg_may_throw(reject, fn.rest, make_node(AST_Array, node, {
elements: node.args.slice(i), elements: node.args.slice(i),
}))) { }))) {
abort = true; abort = true;
@@ -2579,58 +2580,65 @@ Compressor.prototype.compress = function(node) {
} }
} }
function may_throw_arg(reject, node, value) { function arg_may_throw(reject, node, value) {
if (node instanceof AST_DefaultValue) { if (node instanceof AST_DefaultValue) {
return reject(node.value) return reject(node.value)
|| may_throw_arg(reject, node.name, node.value) || arg_may_throw(reject, node.name, node.value)
|| !is_undefined(value) && may_throw_arg(reject, node.name, value); || !is_undefined(value) && arg_may_throw(reject, node.name, value);
} }
if (!value) return !(node instanceof AST_Symbol); if (!value) return !(node instanceof AST_Symbol);
if (node instanceof AST_Destructured) { if (node instanceof AST_Destructured) {
if (node.rest && may_throw_arg(reject, node.rest)) return true; if (node.rest && arg_may_throw(reject, node.rest)) return true;
if (node instanceof AST_DestructuredArray) { if (node instanceof AST_DestructuredArray) {
if (value instanceof AST_Array) return !all(node.elements, function(element, index) { if (value instanceof AST_Array) return !all(node.elements, function(element, index) {
return !may_throw_arg(reject, element, value[index]); return !arg_may_throw(reject, element, value[index]);
}); });
return value.is_string(compressor) && !all(node.elements, function(element) { return value.is_string(compressor) && !all(node.elements, function(element) {
return !may_throw_arg(reject, element); return !arg_may_throw(reject, element);
}); });
} }
if (node instanceof AST_DestructuredObject) { if (node instanceof AST_DestructuredObject) {
if (value.may_throw_on_access(compressor)) return true; if (value.may_throw_on_access(compressor)) return true;
return !all(node.properties, function(prop) { return !all(node.properties, function(prop) {
if (prop.key instanceof AST_Node && reject(prop.key)) return false; if (prop.key instanceof AST_Node && reject(prop.key)) return false;
return !may_throw_arg(reject, prop.value); return !arg_may_throw(reject, prop.value);
}); });
} }
} }
} }
function extract_args() { function extract_args() {
var iife, fn = compressor.self(); if (in_iife_single === false) return;
if (fn instanceof AST_LambdaExpression var iife = compressor.parent(), fn = compressor.self();
&& !is_generator(fn) if (in_iife_single === undefined) {
&& !fn.uses_arguments if (!(fn instanceof AST_LambdaExpression)
&& !fn.pinned() || is_generator(fn)
&& (iife = compressor.parent()) instanceof AST_Call || fn.uses_arguments
&& iife.expression === fn || fn.pinned()
&& is_iife_single(iife) || !(iife instanceof AST_Call)
&& all(iife.args, function(arg) { || iife.expression !== fn
|| !all(iife.args, function(arg) {
return !(arg instanceof AST_Spread); return !(arg instanceof AST_Spread);
})) { })) {
in_iife_single = false;
return;
}
if (!is_iife_single(iife)) return;
in_iife_single = true;
}
var fn_strict = fn.in_strict_mode(compressor) var fn_strict = fn.in_strict_mode(compressor)
&& !fn.parent_scope.resolve(true).in_strict_mode(compressor); && !fn.parent_scope.resolve(true).in_strict_mode(compressor);
var check_arg = false, has_await; var has_await;
if (is_async(fn)) { if (is_async(fn)) {
check_arg = true;
has_await = function(node) { has_await = function(node) {
return node instanceof AST_Symbol && node.name == "await"; return node instanceof AST_Symbol && node.name == "await";
}; };
iife_in_try = true;
} else { } else {
check_arg = find_try(compressor, 1, iife, null, true, true);
has_await = function(node) { has_await = function(node) {
return node instanceof AST_Await && !tw.find_parent(AST_Scope); return node instanceof AST_Await && !tw.find_parent(AST_Scope);
}; };
if (iife_in_try === undefined) iife_in_try = find_try(compressor, 1, iife, null, true, true);
} }
var arg_scope = null; var arg_scope = null;
var tw = new TreeWalker(function(node, descend) { var tw = new TreeWalker(function(node, descend) {
@@ -2671,7 +2679,7 @@ Compressor.prototype.compress = function(node) {
args[len + i] = value; args[len + i] = value;
} }
if (sym instanceof AST_Destructured) { if (sym instanceof AST_Destructured) {
if (check_arg && may_throw_arg(function(node) { if (iife_in_try && arg_may_throw(function(node) {
return node.has_side_effects(compressor); return node.has_side_effects(compressor);
}, sym, arg)) { }, sym, arg)) {
candidates.length = 0; candidates.length = 0;
@@ -2701,7 +2709,6 @@ Compressor.prototype.compress = function(node) {
} }
if (fn.rest) args.push(fn.rest); if (fn.rest) args.push(fn.rest);
} }
}
function extract_candidates(expr, unused) { function extract_candidates(expr, unused) {
hit_stack.push(expr); hit_stack.push(expr);