Skip to content

Commit 24443b6

Browse files
authored
enhance collapse_vars (#5556)
1 parent 154edf0 commit 24443b6

File tree

1 file changed

+106
-99
lines changed

1 file changed

+106
-99
lines changed

lib/compress.js

Lines changed: 106 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,6 +1675,7 @@ Compressor.prototype.compress = function(node) {
16751675
if (may_throw && parent.bcatch && parent.bcatch !== node) return true;
16761676
}
16771677
}
1678+
return false;
16781679
}
16791680

16801681
var identifier_atom = makePredicate("Infinity NaN undefined");
@@ -1917,7 +1918,7 @@ Compressor.prototype.compress = function(node) {
19171918
var in_lambda = last_of(compressor, function(node) {
19181919
return node instanceof AST_Lambda;
19191920
});
1920-
var block_scope, in_loop, in_try, scope;
1921+
var block_scope, iife_in_try, in_iife_single, in_loop, in_try, scope;
19211922
find_loop_scope_try();
19221923
var changed, last_changed, max_iter = 10;
19231924
do {
@@ -2490,10 +2491,10 @@ Compressor.prototype.compress = function(node) {
24902491
var after = stop_after;
24912492
var if_hit = stop_if_hit;
24922493
for (var i = 0; !abort && i < fn.argnames.length; i++) {
2493-
if (may_throw_arg(reject, fn.argnames[i], node.args[i])) abort = true;
2494+
if (arg_may_throw(reject, fn.argnames[i], node.args[i])) abort = true;
24942495
}
24952496
if (!abort) {
2496-
if (fn.rest && may_throw_arg(reject, fn.rest, make_node(AST_Array, node, {
2497+
if (fn.rest && arg_may_throw(reject, fn.rest, make_node(AST_Array, node, {
24972498
elements: node.args.slice(i),
24982499
}))) {
24992500
abort = true;
@@ -2579,128 +2580,134 @@ Compressor.prototype.compress = function(node) {
25792580
}
25802581
}
25812582

2582-
function may_throw_arg(reject, node, value) {
2583+
function arg_may_throw(reject, node, value) {
25832584
if (node instanceof AST_DefaultValue) {
25842585
return reject(node.value)
2585-
|| may_throw_arg(reject, node.name, node.value)
2586-
|| !is_undefined(value) && may_throw_arg(reject, node.name, value);
2586+
|| arg_may_throw(reject, node.name, node.value)
2587+
|| !is_undefined(value) && arg_may_throw(reject, node.name, value);
25872588
}
25882589
if (!value) return !(node instanceof AST_Symbol);
25892590
if (node instanceof AST_Destructured) {
2590-
if (node.rest && may_throw_arg(reject, node.rest)) return true;
2591+
if (node.rest && arg_may_throw(reject, node.rest)) return true;
25912592
if (node instanceof AST_DestructuredArray) {
25922593
if (value instanceof AST_Array) return !all(node.elements, function(element, index) {
2593-
return !may_throw_arg(reject, element, value[index]);
2594+
return !arg_may_throw(reject, element, value[index]);
25942595
});
25952596
return value.is_string(compressor) && !all(node.elements, function(element) {
2596-
return !may_throw_arg(reject, element);
2597+
return !arg_may_throw(reject, element);
25972598
});
25982599
}
25992600
if (node instanceof AST_DestructuredObject) {
26002601
if (value.may_throw_on_access(compressor)) return true;
26012602
return !all(node.properties, function(prop) {
26022603
if (prop.key instanceof AST_Node && reject(prop.key)) return false;
2603-
return !may_throw_arg(reject, prop.value);
2604+
return !arg_may_throw(reject, prop.value);
26042605
});
26052606
}
26062607
}
26072608
}
26082609

26092610
function extract_args() {
2610-
var iife, fn = compressor.self();
2611-
if (fn instanceof AST_LambdaExpression
2612-
&& !is_generator(fn)
2613-
&& !fn.uses_arguments
2614-
&& !fn.pinned()
2615-
&& (iife = compressor.parent()) instanceof AST_Call
2616-
&& iife.expression === fn
2617-
&& is_iife_single(iife)
2618-
&& all(iife.args, function(arg) {
2619-
return !(arg instanceof AST_Spread);
2620-
})) {
2621-
var fn_strict = fn.in_strict_mode(compressor)
2622-
&& !fn.parent_scope.resolve(true).in_strict_mode(compressor);
2623-
var check_arg = false, has_await;
2624-
if (is_async(fn)) {
2625-
check_arg = true;
2626-
has_await = function(node) {
2627-
return node instanceof AST_Symbol && node.name == "await";
2628-
};
2629-
} else {
2630-
check_arg = find_try(compressor, 1, iife, null, true, true);
2631-
has_await = function(node) {
2632-
return node instanceof AST_Await && !tw.find_parent(AST_Scope);
2633-
};
2611+
if (in_iife_single === false) return;
2612+
var iife = compressor.parent(), fn = compressor.self();
2613+
if (in_iife_single === undefined) {
2614+
if (!(fn instanceof AST_LambdaExpression)
2615+
|| is_generator(fn)
2616+
|| fn.uses_arguments
2617+
|| fn.pinned()
2618+
|| !(iife instanceof AST_Call)
2619+
|| iife.expression !== fn
2620+
|| !all(iife.args, function(arg) {
2621+
return !(arg instanceof AST_Spread);
2622+
})) {
2623+
in_iife_single = false;
2624+
return;
26342625
}
2635-
var arg_scope = null;
2636-
var tw = new TreeWalker(function(node, descend) {
2637-
if (!arg) return true;
2638-
if (has_await(node) || node instanceof AST_Yield) {
2639-
arg = null;
2640-
return true;
2641-
}
2642-
if (node instanceof AST_ObjectIdentity && (fn_strict || !arg_scope)) {
2643-
arg = null;
2644-
return true;
2645-
}
2646-
if (node instanceof AST_SymbolRef && fn.variables.has(node.name)) {
2647-
var s = node.definition().scope;
2648-
if (s !== scope) while (s = s.parent_scope) {
2649-
if (s === scope) return true;
2650-
}
2651-
arg = null;
2652-
}
2653-
if (node instanceof AST_Scope && !is_arrow(node)) {
2654-
var save_scope = arg_scope;
2655-
arg_scope = node;
2656-
descend();
2657-
arg_scope = save_scope;
2658-
return true;
2659-
}
2660-
});
2661-
args = iife.args.slice();
2662-
var len = args.length;
2663-
var names = new Dictionary();
2664-
for (var i = fn.argnames.length; --i >= 0;) {
2665-
var sym = fn.argnames[i];
2666-
var arg = args[i];
2667-
var value = null;
2668-
if (sym instanceof AST_DefaultValue) {
2669-
value = sym.value;
2670-
sym = sym.name;
2671-
args[len + i] = value;
2672-
}
2673-
if (sym instanceof AST_Destructured) {
2674-
if (check_arg && may_throw_arg(function(node) {
2675-
return node.has_side_effects(compressor);
2676-
}, sym, arg)) {
2677-
candidates.length = 0;
2678-
break;
2679-
}
2680-
args[len + i] = fn.argnames[i];
2681-
continue;
2626+
if (!is_iife_single(iife)) return;
2627+
in_iife_single = true;
2628+
}
2629+
var fn_strict = fn.in_strict_mode(compressor)
2630+
&& !fn.parent_scope.resolve(true).in_strict_mode(compressor);
2631+
var has_await;
2632+
if (is_async(fn)) {
2633+
has_await = function(node) {
2634+
return node instanceof AST_Symbol && node.name == "await";
2635+
};
2636+
iife_in_try = true;
2637+
} else {
2638+
has_await = function(node) {
2639+
return node instanceof AST_Await && !tw.find_parent(AST_Scope);
2640+
};
2641+
if (iife_in_try === undefined) iife_in_try = find_try(compressor, 1, iife, null, true, true);
2642+
}
2643+
var arg_scope = null;
2644+
var tw = new TreeWalker(function(node, descend) {
2645+
if (!arg) return true;
2646+
if (has_await(node) || node instanceof AST_Yield) {
2647+
arg = null;
2648+
return true;
2649+
}
2650+
if (node instanceof AST_ObjectIdentity && (fn_strict || !arg_scope)) {
2651+
arg = null;
2652+
return true;
2653+
}
2654+
if (node instanceof AST_SymbolRef && fn.variables.has(node.name)) {
2655+
var s = node.definition().scope;
2656+
if (s !== scope) while (s = s.parent_scope) {
2657+
if (s === scope) return true;
26822658
}
2683-
if (names.has(sym.name)) continue;
2684-
names.set(sym.name, true);
2685-
if (value) arg = is_undefined(arg) ? value : null;
2686-
if (!arg && !value) {
2687-
arg = make_node(AST_Undefined, sym).transform(compressor);
2688-
} else if (arg instanceof AST_Lambda && arg.pinned()) {
2689-
arg = null;
2690-
} else if (arg) {
2691-
arg.walk(tw);
2659+
arg = null;
2660+
}
2661+
if (node instanceof AST_Scope && !is_arrow(node)) {
2662+
var save_scope = arg_scope;
2663+
arg_scope = node;
2664+
descend();
2665+
arg_scope = save_scope;
2666+
return true;
2667+
}
2668+
});
2669+
args = iife.args.slice();
2670+
var len = args.length;
2671+
var names = new Dictionary();
2672+
for (var i = fn.argnames.length; --i >= 0;) {
2673+
var sym = fn.argnames[i];
2674+
var arg = args[i];
2675+
var value = null;
2676+
if (sym instanceof AST_DefaultValue) {
2677+
value = sym.value;
2678+
sym = sym.name;
2679+
args[len + i] = value;
2680+
}
2681+
if (sym instanceof AST_Destructured) {
2682+
if (iife_in_try && arg_may_throw(function(node) {
2683+
return node.has_side_effects(compressor);
2684+
}, sym, arg)) {
2685+
candidates.length = 0;
2686+
break;
26922687
}
2693-
if (!arg) continue;
2694-
var candidate = make_node(AST_VarDef, sym, {
2695-
name: sym,
2696-
value: arg,
2697-
});
2698-
candidate.name_index = i;
2699-
candidate.arg_index = value ? len + i : i;
2700-
candidates.unshift([ candidate ]);
2688+
args[len + i] = fn.argnames[i];
2689+
continue;
27012690
}
2702-
if (fn.rest) args.push(fn.rest);
2691+
if (names.has(sym.name)) continue;
2692+
names.set(sym.name, true);
2693+
if (value) arg = is_undefined(arg) ? value : null;
2694+
if (!arg && !value) {
2695+
arg = make_node(AST_Undefined, sym).transform(compressor);
2696+
} else if (arg instanceof AST_Lambda && arg.pinned()) {
2697+
arg = null;
2698+
} else if (arg) {
2699+
arg.walk(tw);
2700+
}
2701+
if (!arg) continue;
2702+
var candidate = make_node(AST_VarDef, sym, {
2703+
name: sym,
2704+
value: arg,
2705+
});
2706+
candidate.name_index = i;
2707+
candidate.arg_index = value ? len + i : i;
2708+
candidates.unshift([ candidate ]);
27032709
}
2710+
if (fn.rest) args.push(fn.rest);
27042711
}
27052712

27062713
function extract_candidates(expr, unused) {

0 commit comments

Comments
 (0)