Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa2a9fbedb | ||
|
|
3596b4feda | ||
|
|
51deeff72e | ||
|
|
4c227cc6bd | ||
|
|
2426657daa | ||
|
|
e1b03d0235 | ||
|
|
f1b3e9df1e | ||
|
|
fcc87edb71 | ||
|
|
8b464331ba | ||
|
|
9f57920566 | ||
|
|
933ca9ddd8 |
228
lib/compress.js
228
lib/compress.js
@@ -1598,8 +1598,7 @@ Compressor.prototype.compress = function(node) {
|
||||
AST_Destructured.DEFMETHOD("convert_symbol", convert_destructured);
|
||||
function convert_symbol(type, process) {
|
||||
var node = make_node(type, this, this);
|
||||
process(node, this);
|
||||
return node;
|
||||
return process(node, this) || node;
|
||||
}
|
||||
AST_SymbolDeclaration.DEFMETHOD("convert_symbol", convert_symbol);
|
||||
AST_SymbolRef.DEFMETHOD("convert_symbol", convert_symbol);
|
||||
@@ -1951,13 +1950,25 @@ Compressor.prototype.compress = function(node) {
|
||||
return statements;
|
||||
|
||||
function last_of(compressor, predicate) {
|
||||
var block = compressor.self(), stat, level = 0;
|
||||
var block = compressor.self(), level = 0;
|
||||
do {
|
||||
do {
|
||||
if (block instanceof AST_Catch) {
|
||||
block = compressor.parent(level++);
|
||||
} else if (block instanceof AST_LabeledStatement) {
|
||||
block = block.body;
|
||||
}
|
||||
var stat = null;
|
||||
while (true) {
|
||||
if (predicate(block)) return true;
|
||||
block = compressor.parent(level++);
|
||||
} while (block instanceof AST_If && (stat = block));
|
||||
} while ((block instanceof AST_BlockStatement || block instanceof AST_Scope)
|
||||
if (!(block instanceof AST_If)) break;
|
||||
stat = block;
|
||||
}
|
||||
} while (stat
|
||||
&& (block instanceof AST_BlockStatement
|
||||
|| block instanceof AST_Catch
|
||||
|| block instanceof AST_Scope
|
||||
|| block instanceof AST_Try)
|
||||
&& is_last_statement(block.body, stat));
|
||||
}
|
||||
|
||||
@@ -3391,6 +3402,7 @@ Compressor.prototype.compress = function(node) {
|
||||
var changed = false;
|
||||
var parent = compressor.parent();
|
||||
var self = compressor.self();
|
||||
var exit, exit_defs, merge_exit;
|
||||
var in_iife = in_lambda && parent && parent.TYPE == "Call" && parent.expression === self;
|
||||
var chain_if_returns = in_lambda && compressor.option("conditionals") && compressor.option("sequences");
|
||||
var multiple_if_returns = has_multiple_if_returns(statements);
|
||||
@@ -3446,6 +3458,7 @@ Compressor.prototype.compress = function(node) {
|
||||
stat.condition = cond;
|
||||
statements[j] = stat.body;
|
||||
stat.body = next;
|
||||
if (next === exit) exit = null;
|
||||
statements[i] = stat;
|
||||
statements[i] = stat.transform(compressor);
|
||||
continue;
|
||||
@@ -3489,6 +3502,7 @@ Compressor.prototype.compress = function(node) {
|
||||
changed = true;
|
||||
stat = stat.clone();
|
||||
stat.alternative = next;
|
||||
if (next === exit) exit = null;
|
||||
statements.splice(i, 1, stat.transform(compressor));
|
||||
statements.splice(j, 1);
|
||||
continue;
|
||||
@@ -3532,6 +3546,11 @@ Compressor.prototype.compress = function(node) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (stat instanceof AST_Exit) {
|
||||
exit = stat;
|
||||
exit_defs = null;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
|
||||
@@ -3553,7 +3572,25 @@ Compressor.prototype.compress = function(node) {
|
||||
}
|
||||
|
||||
function can_drop_abort(ab) {
|
||||
if (ab instanceof AST_Return) return in_lambda && is_undefined(ab.value);
|
||||
if (ab instanceof AST_Exit) {
|
||||
if (exit && exit.equivalent_to(ab)) {
|
||||
if (!exit_defs) {
|
||||
exit_defs = new Dictionary();
|
||||
exit.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_SymbolRef) exit_defs.set(node.name, node.definition());
|
||||
}));
|
||||
}
|
||||
var abort = false;
|
||||
ab.walk(new TreeWalker(function(node) {
|
||||
if (abort) return true;
|
||||
if (node instanceof AST_SymbolRef && exit_defs.get(node.name) !== node.definition()) {
|
||||
return abort = true;
|
||||
}
|
||||
}));
|
||||
if (!abort) return merge_exit = true;
|
||||
}
|
||||
return in_lambda && ab instanceof AST_Return && is_undefined(ab.value);
|
||||
}
|
||||
if (!(ab instanceof AST_LoopControl)) return false;
|
||||
var lct = compressor.loopcontrol_target(ab);
|
||||
if (ab instanceof AST_Continue) return match_target(loop_body(lct));
|
||||
@@ -3562,6 +3599,7 @@ Compressor.prototype.compress = function(node) {
|
||||
}
|
||||
|
||||
function can_merge_flow(ab) {
|
||||
merge_exit = false;
|
||||
if (!can_drop_abort(ab)) return false;
|
||||
for (var j = statements.length; --j > i;) {
|
||||
var stat = statements[j];
|
||||
@@ -3581,7 +3619,16 @@ Compressor.prototype.compress = function(node) {
|
||||
function extract_functions() {
|
||||
var defuns = [];
|
||||
var lexical = false;
|
||||
var tail = statements.splice(i + 1).filter(function(stat) {
|
||||
var start = i + 1;
|
||||
var end;
|
||||
if (merge_exit) {
|
||||
end = statements.lastIndexOf(exit);
|
||||
if (end < 0) end = statements.length;
|
||||
} else {
|
||||
end = statements.length;
|
||||
exit = null;
|
||||
}
|
||||
var tail = statements.splice(start, end - start).filter(function(stat) {
|
||||
if (stat instanceof AST_LambdaDefinition) {
|
||||
defuns.push(stat);
|
||||
return false;
|
||||
@@ -3600,7 +3647,7 @@ Compressor.prototype.compress = function(node) {
|
||||
block = last.body;
|
||||
}
|
||||
block.pop();
|
||||
if (ab.value) block.push(make_node(AST_SimpleStatement, ab.value, { body: ab.value }));
|
||||
if (!merge_exit && ab.value) block.push(make_node(AST_SimpleStatement, ab.value, { body: ab.value }));
|
||||
return body;
|
||||
}
|
||||
|
||||
@@ -3641,6 +3688,11 @@ Compressor.prototype.compress = function(node) {
|
||||
function eliminate_dead_code(statements, compressor) {
|
||||
var has_quit;
|
||||
var self = compressor.self();
|
||||
if (self instanceof AST_Catch) {
|
||||
self = compressor.parent();
|
||||
} else if (self instanceof AST_LabeledStatement) {
|
||||
self = self.body;
|
||||
}
|
||||
for (var i = 0, n = 0, len = statements.length; i < len; i++) {
|
||||
var stat = statements[i];
|
||||
if (stat instanceof AST_LoopControl) {
|
||||
@@ -5929,10 +5981,19 @@ Compressor.prototype.compress = function(node) {
|
||||
});
|
||||
|
||||
OPT(AST_LabeledStatement, function(self, compressor) {
|
||||
if (compressor.option("dead_code")
|
||||
&& self.body instanceof AST_Break
|
||||
&& compressor.loopcontrol_target(self.body) === self.body) {
|
||||
return make_node(AST_EmptyStatement, self);
|
||||
if (self.body instanceof AST_If || self.body instanceof AST_Break) {
|
||||
var body = tighten_body([ self.body ], compressor);
|
||||
switch (body.length) {
|
||||
case 0:
|
||||
self.body = make_node(AST_EmptyStatement, self);
|
||||
break;
|
||||
case 1:
|
||||
self.body = body[0];
|
||||
break;
|
||||
default:
|
||||
self.body = make_node(AST_BlockStatement, self, { body: body });
|
||||
break;
|
||||
}
|
||||
}
|
||||
return compressor.option("unused") && self.label.references.length == 0 ? self.body : self;
|
||||
});
|
||||
@@ -6886,7 +6947,7 @@ Compressor.prototype.compress = function(node) {
|
||||
node.properties = properties;
|
||||
return node;
|
||||
}
|
||||
if (node instanceof AST_SymbolDeclaration) return node.definition().id in in_use_ids ? node : null;
|
||||
if (node instanceof AST_SymbolDeclaration) return trim_decl(node);
|
||||
});
|
||||
var tt = new TreeTransformer(function(node, descend, in_list) {
|
||||
var parent = tt.parent();
|
||||
@@ -7001,9 +7062,7 @@ Compressor.prototype.compress = function(node) {
|
||||
} else {
|
||||
var trimmed = trim_destructured(rest, make_node(AST_Array, parent, {
|
||||
elements: args.slice(argnames.length),
|
||||
}), function(node) {
|
||||
return node.definition().id in in_use_ids ? node : null;
|
||||
}, !node.uses_arguments, rest);
|
||||
}), trim_decl, !node.uses_arguments, rest);
|
||||
rest = trimmed.name;
|
||||
args.length = argnames.length;
|
||||
if (trimmed.value.elements.length) [].push.apply(args, trimmed.value.elements);
|
||||
@@ -7033,6 +7092,8 @@ Compressor.prototype.compress = function(node) {
|
||||
} else if (trim) {
|
||||
log(sym, "Dropping unused function argument {name}");
|
||||
argnames.pop();
|
||||
def.eliminated++;
|
||||
sym.unused = true;
|
||||
} else {
|
||||
sym.unused = true;
|
||||
}
|
||||
@@ -7042,9 +7103,7 @@ Compressor.prototype.compress = function(node) {
|
||||
if (!args || spread < i) {
|
||||
funarg = sym.transform(trimmer);
|
||||
} else {
|
||||
var trimmed = trim_destructured(sym, args[i], function(node) {
|
||||
return node.definition().id in in_use_ids ? node : null;
|
||||
}, trim_value, sym);
|
||||
var trimmed = trim_destructured(sym, args[i], trim_decl, trim_value, sym);
|
||||
funarg = trimmed.name;
|
||||
if (trimmed.value) args[i] = trimmed.value;
|
||||
}
|
||||
@@ -7644,6 +7703,12 @@ Compressor.prototype.compress = function(node) {
|
||||
return (node instanceof AST_DefaultValue ? node.name : node) instanceof AST_SymbolDeclaration;
|
||||
}
|
||||
|
||||
function trim_decl(node) {
|
||||
if (node.definition().id in in_use_ids) return node;
|
||||
if (node instanceof AST_SymbolFunarg) node.unused = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
function trim_default(trimmer, node) {
|
||||
node.value = node.value.transform(tt);
|
||||
var name = node.name.transform(trimmer);
|
||||
@@ -10482,9 +10547,9 @@ Compressor.prototype.compress = function(node) {
|
||||
return try_evaluate(compressor, self);
|
||||
|
||||
function make_void_lhs(orig) {
|
||||
return make_node(AST_Dot, orig, {
|
||||
return make_node(AST_Sub, orig, {
|
||||
expression: make_node(AST_Array, orig, { elements: [] }),
|
||||
property: "e",
|
||||
property: make_node(AST_Number, orig, { value: 0 }),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10722,7 +10787,9 @@ Compressor.prototype.compress = function(node) {
|
||||
});
|
||||
child = scope;
|
||||
scope = compressor.parent(level++);
|
||||
if (scope instanceof AST_DWLoop) {
|
||||
if (scope instanceof AST_ClassField) {
|
||||
if (!scope.static) return false;
|
||||
} else if (scope instanceof AST_DWLoop) {
|
||||
in_loop = [];
|
||||
} else if (scope instanceof AST_For) {
|
||||
if (scope.init === child) continue;
|
||||
@@ -10837,6 +10904,7 @@ Compressor.prototype.compress = function(node) {
|
||||
}));
|
||||
|
||||
function process(ref, name) {
|
||||
if (name.unused) return make_void_lhs(name);
|
||||
var def = name.definition();
|
||||
def.assignments++;
|
||||
def.references.push(ref);
|
||||
@@ -11997,6 +12065,8 @@ Compressor.prototype.compress = function(node) {
|
||||
if ((def.scope !== self.scope.resolve() || def.in_loop)
|
||||
&& (!compressor.option("reduce_funcs") || def.escaped.depth == 1 || fixed.inlined)) {
|
||||
single_use = false;
|
||||
} else if (def.redefined()) {
|
||||
single_use = false;
|
||||
} else if (recursive_ref(compressor, def, fixed)) {
|
||||
single_use = false;
|
||||
} else if (fixed.name && fixed.name.definition() !== def) {
|
||||
@@ -13411,7 +13481,7 @@ Compressor.prototype.compress = function(node) {
|
||||
def(AST_Assign, noop);
|
||||
def(AST_Await, function(compressor, scope, no_return, in_loop) {
|
||||
var self = this;
|
||||
var inlined = sync(self.expression).try_inline(compressor, scope, no_return, in_loop);
|
||||
var inlined = self.expression.try_inline(compressor, scope, no_return, in_loop, true);
|
||||
if (!inlined) return;
|
||||
if (!no_return) scan_local_returns(inlined, function(node) {
|
||||
node.in_bool = false;
|
||||
@@ -13426,40 +13496,20 @@ Compressor.prototype.compress = function(node) {
|
||||
body: make_node(AST_Await, self, { expression: make_node(AST_Number, self, { value: 0 })}),
|
||||
}) ],
|
||||
});
|
||||
|
||||
function sync(node) {
|
||||
if (!no_return) return node;
|
||||
if (node.TYPE != "Call") return node;
|
||||
var fn = node.expression;
|
||||
switch (fn.CTOR) {
|
||||
case AST_AsyncArrow:
|
||||
fn = make_node(AST_Arrow, fn, fn);
|
||||
break;
|
||||
case AST_AsyncFunction:
|
||||
fn = make_node(AST_Function, fn, fn);
|
||||
break;
|
||||
case AST_AsyncGeneratorFunction:
|
||||
fn = make_node(AST_GeneratorFunction, fn, fn);
|
||||
break;
|
||||
default:
|
||||
return node;
|
||||
}
|
||||
node = node.clone();
|
||||
node.expression = fn;
|
||||
return node;
|
||||
}
|
||||
});
|
||||
def(AST_Binary, function(compressor, scope, no_return, in_loop) {
|
||||
def(AST_Binary, function(compressor, scope, no_return, in_loop, in_await) {
|
||||
if (no_return === undefined) return;
|
||||
var self = this;
|
||||
var op = self.operator;
|
||||
if (!lazy_op[op]) return;
|
||||
var inlined = self.right.try_inline(compressor, scope, no_return, in_loop);
|
||||
var inlined = self.right.try_inline(compressor, scope, no_return, in_loop, in_await);
|
||||
if (!inlined) return;
|
||||
return make_node(AST_If, self, {
|
||||
condition: make_condition(self.left),
|
||||
body: inlined,
|
||||
alternative: no_return ? null : make_node(AST_Return, self, { value: null }),
|
||||
alternative: no_return ? null : make_node(AST_Return, self, {
|
||||
value: make_node(AST_Undefined, self).transform(compressor),
|
||||
}),
|
||||
});
|
||||
|
||||
function make_condition(cond) {
|
||||
@@ -13488,7 +13538,7 @@ Compressor.prototype.compress = function(node) {
|
||||
body[last] = inlined;
|
||||
return this;
|
||||
});
|
||||
def(AST_Call, function(compressor, scope, no_return, in_loop) {
|
||||
def(AST_Call, function(compressor, scope, no_return, in_loop, in_await) {
|
||||
if (compressor.option("inline") < 4) return;
|
||||
var call = this;
|
||||
if (call.is_expr_pure(compressor)) return;
|
||||
@@ -13503,7 +13553,6 @@ Compressor.prototype.compress = function(node) {
|
||||
if (fn.body[0] instanceof AST_Directive) return;
|
||||
if (fn.contains_this()) return;
|
||||
if (!scope) scope = find_scope(compressor);
|
||||
if (in_async_generator(scope)) return;
|
||||
var defined = new Dictionary();
|
||||
defined.set("NaN", true);
|
||||
while (!(scope instanceof AST_Scope)) {
|
||||
@@ -13521,7 +13570,7 @@ Compressor.prototype.compress = function(node) {
|
||||
}
|
||||
defined.set("arguments", true);
|
||||
}
|
||||
var async = is_async(fn);
|
||||
var async = !in_await && is_async(fn);
|
||||
if (async) {
|
||||
if (!compressor.option("awaits")) return;
|
||||
if (!is_async(scope)) return;
|
||||
@@ -13563,15 +13612,40 @@ Compressor.prototype.compress = function(node) {
|
||||
if (has_arg_refs(fn, fn.rest)) return;
|
||||
simple_argnames = false;
|
||||
}
|
||||
if (no_return && !all(fn.body, function(stat) {
|
||||
var abort = false;
|
||||
stat.walk(new TreeWalker(function(node) {
|
||||
if (abort) return true;
|
||||
if (async && node instanceof AST_Await || node instanceof AST_Return) return abort = true;
|
||||
if (node instanceof AST_Scope && node !== fn) return true;
|
||||
}));
|
||||
return !abort;
|
||||
})) return;
|
||||
var verify_body;
|
||||
if (no_return) {
|
||||
verify_body = function(stat) {
|
||||
var abort = false;
|
||||
stat.walk(new TreeWalker(function(node) {
|
||||
if (abort) return true;
|
||||
if (async && node instanceof AST_Await || node instanceof AST_Return) return abort = true;
|
||||
if (node instanceof AST_Scope) return true;
|
||||
}));
|
||||
return !abort;
|
||||
};
|
||||
} else if (in_await && !is_async(fn) || in_async_generator(scope)) {
|
||||
verify_body = function(stat) {
|
||||
var abort = false;
|
||||
var find_return = new TreeWalker(function(node) {
|
||||
if (abort) return true;
|
||||
if (node instanceof AST_Return) return abort = true;
|
||||
if (node instanceof AST_Scope) return true;
|
||||
});
|
||||
stat.walk(new TreeWalker(function(node) {
|
||||
if (abort) return true;
|
||||
if (node instanceof AST_Try) {
|
||||
if (node.bfinally && all(node.body, function(stat) {
|
||||
stat.walk(find_return);
|
||||
return !abort;
|
||||
}) && node.bcatch) node.bcatch.walk(find_return);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Scope) return true;
|
||||
}));
|
||||
return !abort;
|
||||
};
|
||||
}
|
||||
if (verify_body && !all(fn.body, verify_body)) return;
|
||||
if (!safe_from_await_yield(fn, avoid_await_yield(compressor, scope))) return;
|
||||
fn.functions.each(function(def, name) {
|
||||
scope.functions.set(name, def);
|
||||
@@ -13589,7 +13663,7 @@ Compressor.prototype.compress = function(node) {
|
||||
if (def.orig.length == 1 && fn.functions.has(name)) return;
|
||||
if (!all(def.orig, function(sym) {
|
||||
if (sym instanceof AST_SymbolConst) return false;
|
||||
if (sym instanceof AST_SymbolFunarg) return def.scope.resolve() !== fn;
|
||||
if (sym instanceof AST_SymbolFunarg) return !sym.unused && def.scope.resolve() !== fn;
|
||||
if (sym instanceof AST_SymbolLet) return false;
|
||||
return true;
|
||||
})) return;
|
||||
@@ -13659,7 +13733,9 @@ Compressor.prototype.compress = function(node) {
|
||||
if (is_undefined(value)) return;
|
||||
node.value = make_node(AST_Await, call, { expression: value });
|
||||
});
|
||||
body.push(make_node(AST_Return, call, { value: null }));
|
||||
body.push(make_node(AST_Return, call, {
|
||||
value: in_async_generator(scope) ? make_node(AST_Undefined, call).transform(compressor) : null,
|
||||
}));
|
||||
}
|
||||
return inlined;
|
||||
|
||||
@@ -13669,10 +13745,10 @@ Compressor.prototype.compress = function(node) {
|
||||
syms.add(def.id, sym);
|
||||
}
|
||||
});
|
||||
def(AST_Conditional, function(compressor, scope, no_return, in_loop) {
|
||||
def(AST_Conditional, function(compressor, scope, no_return, in_loop, in_await) {
|
||||
var self = this;
|
||||
var body = self.consequent.try_inline(compressor, scope, no_return, in_loop);
|
||||
var alt = self.alternative.try_inline(compressor, scope, no_return, in_loop);
|
||||
var body = self.consequent.try_inline(compressor, scope, no_return, in_loop, in_await);
|
||||
var alt = self.alternative.try_inline(compressor, scope, no_return, in_loop, in_await);
|
||||
if (!body && !alt) return;
|
||||
return make_node(AST_If, self, {
|
||||
condition: self.condition,
|
||||
@@ -13707,7 +13783,7 @@ Compressor.prototype.compress = function(node) {
|
||||
if (body) this.body = body;
|
||||
var obj = this.object;
|
||||
if (obj instanceof AST_Sequence) {
|
||||
var inlined = inline_sequence(compressor, scope, true, in_loop, obj, 1);
|
||||
var inlined = inline_sequence(compressor, scope, true, in_loop, false, obj, 1);
|
||||
if (inlined) {
|
||||
this.object = obj.tail_node();
|
||||
inlined.body.push(this);
|
||||
@@ -13726,7 +13802,7 @@ Compressor.prototype.compress = function(node) {
|
||||
}
|
||||
var cond = this.condition;
|
||||
if (cond instanceof AST_Sequence) {
|
||||
var inlined = inline_sequence(compressor, scope, true, in_loop, cond, 1);
|
||||
var inlined = inline_sequence(compressor, scope, true, in_loop, false, cond, 1);
|
||||
if (inlined) {
|
||||
this.condition = cond.tail_node();
|
||||
inlined.body.push(this);
|
||||
@@ -13758,10 +13834,10 @@ Compressor.prototype.compress = function(node) {
|
||||
var value = this.value;
|
||||
return value && value.try_inline(compressor, scope, undefined, in_loop === "try");
|
||||
});
|
||||
function inline_sequence(compressor, scope, no_return, in_loop, node, skip) {
|
||||
function inline_sequence(compressor, scope, no_return, in_loop, in_await, node, skip) {
|
||||
var body = [], exprs = node.expressions, no_ret = no_return;
|
||||
for (var i = exprs.length - (skip || 0), j = i; --i >= 0; no_ret = true) {
|
||||
var inlined = exprs[i].try_inline(compressor, scope, no_ret, in_loop);
|
||||
for (var i = exprs.length - (skip || 0), j = i; --i >= 0; no_ret = true, in_await = false) {
|
||||
var inlined = exprs[i].try_inline(compressor, scope, no_ret, in_loop, in_await);
|
||||
if (!inlined) continue;
|
||||
flush();
|
||||
body.push(inlined);
|
||||
@@ -13780,8 +13856,8 @@ Compressor.prototype.compress = function(node) {
|
||||
j = i;
|
||||
}
|
||||
}
|
||||
def(AST_Sequence, function(compressor, scope, no_return, in_loop) {
|
||||
return inline_sequence(compressor, scope, no_return, in_loop, this);
|
||||
def(AST_Sequence, function(compressor, scope, no_return, in_loop, in_await) {
|
||||
return inline_sequence(compressor, scope, no_return, in_loop, in_await, this);
|
||||
});
|
||||
def(AST_SimpleStatement, function(compressor, scope, no_return, in_loop) {
|
||||
var body = this.body;
|
||||
@@ -13797,12 +13873,12 @@ Compressor.prototype.compress = function(node) {
|
||||
});
|
||||
return body.try_inline(compressor, scope, no_return || false, in_loop);
|
||||
});
|
||||
def(AST_UnaryPrefix, function(compressor, scope, no_return, in_loop) {
|
||||
def(AST_UnaryPrefix, function(compressor, scope, no_return, in_loop, in_await) {
|
||||
var self = this;
|
||||
var op = self.operator;
|
||||
if (unary_side_effects[op]) return;
|
||||
if (!no_return && op == "void") no_return = false;
|
||||
var inlined = self.expression.try_inline(compressor, scope, no_return, in_loop);
|
||||
var inlined = self.expression.try_inline(compressor, scope, no_return, in_loop, in_await);
|
||||
if (!inlined) return;
|
||||
if (!no_return) scan_local_returns(inlined, function(node) {
|
||||
node.in_bool = false;
|
||||
@@ -13820,7 +13896,7 @@ Compressor.prototype.compress = function(node) {
|
||||
if (body) this.body = body;
|
||||
var exp = this.expression;
|
||||
if (exp instanceof AST_Sequence) {
|
||||
var inlined = inline_sequence(compressor, scope, true, in_loop, exp, 1);
|
||||
var inlined = inline_sequence(compressor, scope, true, in_loop, false, exp, 1);
|
||||
if (inlined) {
|
||||
this.expression = exp.tail_node();
|
||||
inlined.body.push(this);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.16.1",
|
||||
"version": "3.16.2",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
|
||||
@@ -3021,3 +3021,157 @@ issue_5506: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return 42;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return 42;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
FAIL;
|
||||
} catch (e) {
|
||||
return console.log("foo");
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
FAIL;
|
||||
} catch (e) {
|
||||
return console.log("foo");
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_4: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return {
|
||||
then() {
|
||||
console.log("foo");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return {
|
||||
then() {
|
||||
console.log("foo");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"bar",
|
||||
"baz",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
@@ -3330,3 +3330,113 @@ issue_5512: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
issue_5531_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
class A {
|
||||
p = function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
}();
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect: {
|
||||
class A {
|
||||
p = function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
}();
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5531_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
class A {
|
||||
static p = function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
}();
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect: {
|
||||
class A {
|
||||
static p = (a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++), void 0);
|
||||
}
|
||||
var a;
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect_stdout: "foo"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5531_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
class A {
|
||||
static {
|
||||
(function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
})();
|
||||
}
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect: {
|
||||
class A {
|
||||
static {
|
||||
a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++),
|
||||
void 0;
|
||||
var a;
|
||||
}
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect_stdout: "foo"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
@@ -1872,3 +1872,37 @@ issue_5476: {
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_5516: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function() {
|
||||
try {} catch (a) {
|
||||
(function f() {
|
||||
a;
|
||||
})();
|
||||
}
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function() {
|
||||
try {} catch (a) {
|
||||
void a;
|
||||
}
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
@@ -541,7 +541,7 @@ inline_side_effects_2: {
|
||||
}
|
||||
expect: {
|
||||
var a = 42;
|
||||
[ [].e = --a ] = [ console ];
|
||||
[ [][0] = --a ] = [ console ];
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
@@ -1558,7 +1558,7 @@ issue_4502_4: {
|
||||
(function(a, b = console.log("FAIL")) {})(..."" + console.log(42));
|
||||
}
|
||||
expect: {
|
||||
[ , [].e = console.log("FAIL") ] = [ ..."" + console.log(42) ];
|
||||
[ , [][0] = console.log("FAIL") ] = [ ..."" + console.log(42) ];
|
||||
}
|
||||
expect_stdout: "42"
|
||||
node_version: ">=6"
|
||||
@@ -2183,7 +2183,7 @@ issue_5340_2: {
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
[ [].e = 0 ] = [ ({ p: a } = true).q ];
|
||||
[ [][0] = 0 ] = [ ({ p: a } = true).q ];
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
@@ -2462,3 +2462,370 @@ issue_5485: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_1_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_1_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ] = []) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ] = []) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_3_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, c = null) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_3_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, c = null) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_4_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, [ c ] = []) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_4_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, [ c ] = []) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5536: {
|
||||
options = {
|
||||
inline: true,
|
||||
keep_fargs: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function*() {
|
||||
(([], a = 42) => {})([]);
|
||||
console.log(typeof a);
|
||||
})().next();
|
||||
}
|
||||
expect: {
|
||||
(function*() {
|
||||
[ , [][0] = 0 ] = [ [] ],
|
||||
void 0;
|
||||
console.log(typeof a);
|
||||
})().next();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -3497,7 +3497,7 @@ issue_5314_2: {
|
||||
A = this;
|
||||
new function() {
|
||||
[ {
|
||||
[console.log(this === A ? "FAIL" : "PASS")]: [].e,
|
||||
[console.log(this === A ? "FAIL" : "PASS")]: [][0],
|
||||
} ] = [ 42 ];
|
||||
}();
|
||||
}
|
||||
@@ -3646,3 +3646,87 @@ issue_5485: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})([]);
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})([]);
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -3685,3 +3685,85 @@ issue_5271: {
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5533_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5533_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -629,7 +629,7 @@ inline_binary_and: {
|
||||
return void "moo";
|
||||
return;
|
||||
} else
|
||||
return;
|
||||
return void 0;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
@@ -5582,7 +5582,7 @@ issue_3835: {
|
||||
return f();
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_stdout: RangeError("Maximum call stack size exceeded")
|
||||
}
|
||||
|
||||
issue_3836_1: {
|
||||
@@ -7835,7 +7835,7 @@ issue_5249_1: {
|
||||
while (console.log("FAIL 2"));
|
||||
return;
|
||||
} else
|
||||
return;
|
||||
return void 0;
|
||||
throw "FAIL 3";
|
||||
}());
|
||||
}
|
||||
|
||||
@@ -850,3 +850,170 @@ issue_866_2: {
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
identical_returns_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
if (console.log("foo"))
|
||||
return 42;
|
||||
else
|
||||
while (console.log("bar"));
|
||||
return 42;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
if (!console.log("foo"))
|
||||
while (console.log("bar"));
|
||||
return 42;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"42",
|
||||
]
|
||||
}
|
||||
|
||||
identical_returns_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
if (console.log("foo"))
|
||||
while (console.log("FAIL"));
|
||||
else
|
||||
return "bar";
|
||||
return "bar";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
if (console.log("foo"))
|
||||
while (console.log("FAIL"));
|
||||
return "bar";
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
}
|
||||
|
||||
identical_returns_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
if (a)
|
||||
return 42;
|
||||
if (a)
|
||||
return;
|
||||
return 42;
|
||||
}
|
||||
if (f(console))
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
if (a)
|
||||
return 42;
|
||||
if (a)
|
||||
;
|
||||
else
|
||||
return 42;
|
||||
}
|
||||
if (f(console))
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4374: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
console.log(f(console));
|
||||
function f(a) {
|
||||
if (console) return 0;
|
||||
if (a) return 1;
|
||||
return 0;
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
console.log(function(a) {
|
||||
return !console && a ? 1 : 0;
|
||||
}(console));
|
||||
})();
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
issue_5521: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
if (console)
|
||||
try {
|
||||
return "FAIL";
|
||||
} finally {
|
||||
return;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
if (console)
|
||||
try {
|
||||
return "FAIL";
|
||||
} finally {
|
||||
return;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_5523: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
if (console)
|
||||
try {
|
||||
FAIL;
|
||||
} finally {
|
||||
return;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
if (console)
|
||||
try {
|
||||
FAIL;
|
||||
} finally {
|
||||
return;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ labels_5: {
|
||||
labels_6: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
out: break out;
|
||||
@@ -208,6 +209,59 @@ labels_10: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
labels_11: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
L: if (console.log("PASS"))
|
||||
break L;
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
labels_12: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
L: try {
|
||||
if (console.log("foo"))
|
||||
break L;
|
||||
throw "bar";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
break L;
|
||||
} finally {
|
||||
if (console.log("baz"))
|
||||
break L;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
L: try {
|
||||
if (!console.log("foo"))
|
||||
throw "bar";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
if (console.log("baz"))
|
||||
break L;
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
}
|
||||
|
||||
issue_4466_1: {
|
||||
mangle = {
|
||||
v8: false,
|
||||
@@ -327,3 +381,53 @@ issue_4466_2_toplevel_v8: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5522: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
L: try {
|
||||
return "FAIL";
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
return "PASS";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
L: try {
|
||||
return "FAIL";
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
return "PASS";
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5524: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
L: try {
|
||||
FAIL;
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
L: try {
|
||||
FAIL;
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -892,6 +892,40 @@ if_return_2: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
if_return_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
let b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
let b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
do_if_continue_1: {
|
||||
options = {
|
||||
if_return: true,
|
||||
|
||||
@@ -308,6 +308,7 @@ issue_4679: {
|
||||
issue_5266: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
[
|
||||
|
||||
@@ -648,7 +648,7 @@ drop_new_function: {
|
||||
}
|
||||
expect: {
|
||||
void ([ ... {
|
||||
[console.log("PASS")]: [].e,
|
||||
[console.log("PASS")]: [][0],
|
||||
}] = []);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -1363,3 +1363,171 @@ issue_5391: {
|
||||
expect_stdout: "NaN"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_5533_1_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_1_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...[ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...[ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ if_return: {
|
||||
if (w) {
|
||||
if (y) return;
|
||||
} else if (z) return;
|
||||
return x == y || (x && w(), y && z()), !0;
|
||||
return x != y && (x && w(), y && z()), !0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,3 +613,35 @@ issue_4954: {
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5516: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(typeof function() {
|
||||
{
|
||||
let a;
|
||||
}
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(typeof function() {
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -907,7 +907,7 @@ drop_body: {
|
||||
})([ console.log("baz") ]);
|
||||
}
|
||||
expect: {
|
||||
[ [ , [].e = console.log("foo") ] ] = [ [ console.log("baz") ] ];
|
||||
[ [ , [][0] = console.log("foo") ] ] = [ [ console.log("baz") ] ];
|
||||
}
|
||||
expect_stdout: [
|
||||
"baz",
|
||||
@@ -1467,6 +1467,80 @@ issue_5385_2: {
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5385_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
return function() {
|
||||
try {
|
||||
throw console.log("foo");
|
||||
} catch (e) {
|
||||
return console.log("bar");
|
||||
}
|
||||
}();
|
||||
})().next();
|
||||
console.log("moo");
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
try {
|
||||
throw console.log("foo");
|
||||
} catch (e) {
|
||||
return console.log("bar");
|
||||
}
|
||||
return void 0;
|
||||
})().next();
|
||||
console.log("moo");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"moo",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5385_4: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
resolve(console.log("FAIL"));
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
return "PASS";
|
||||
}
|
||||
}();
|
||||
})().next().then(o => console.log(o.value, o.done));
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
resolve(console.log("FAIL"));
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
return "PASS";
|
||||
}
|
||||
}();
|
||||
})().next().then(o => console.log(o.value, o.done));
|
||||
}
|
||||
expect_stdout: "PASS true"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5425: {
|
||||
options = {
|
||||
assignments: true,
|
||||
@@ -1562,3 +1636,39 @@ issue_5506: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5526: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
try {
|
||||
return function() {
|
||||
while (console.log("foo"));
|
||||
}();
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
try {
|
||||
while (console.log("foo"));
|
||||
return void 0;
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
@@ -778,9 +778,9 @@ function compare_run_code(code, minify_options, result_cache, max_timeout) {
|
||||
function run(code, timeout) {
|
||||
if (minify_options.module) code = [
|
||||
'"use strict";',
|
||||
"(async function(){",
|
||||
"(async()=>{",
|
||||
code,
|
||||
"})();"
|
||||
'})().catch(e=>process.on("exit",()=>{throw e}));',
|
||||
].join("\n");
|
||||
return run_code(code, toplevel, result_cache, timeout);
|
||||
}
|
||||
|
||||
@@ -2104,9 +2104,9 @@ if (require.main !== module) {
|
||||
function run_code(code, toplevel, timeout) {
|
||||
if (async && has_await) code = [
|
||||
'"use strict";',
|
||||
"(async function(){",
|
||||
"(async()=>{",
|
||||
code,
|
||||
"})();"
|
||||
'})().catch(e=>process.on("exit",()=>{throw e}));',
|
||||
].join("\n");
|
||||
return sandbox.run_code(sandbox.patch_module_statements(code), toplevel, timeout);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user