expand test options (#4475)
- fix corner cases in `hoist_vars` & `keep_fnames`
This commit is contained in:
100
lib/compress.js
100
lib/compress.js
@@ -6171,6 +6171,7 @@ merge(Compressor.prototype, {
|
||||
if (var_decl <= 1) hoist_vars = false;
|
||||
}
|
||||
if (!hoist_funs && !hoist_vars) return;
|
||||
var consts = Object.create(null);
|
||||
var dirs = [];
|
||||
var hoisted = [];
|
||||
var vars = new Dictionary(), vars_found = 0;
|
||||
@@ -6186,6 +6187,12 @@ merge(Compressor.prototype, {
|
||||
return make_node(AST_EmptyStatement, node);
|
||||
}
|
||||
if (hoist_vars && node instanceof AST_Var) {
|
||||
if (!all(node.definitions, function(defn) {
|
||||
var sym = defn.name;
|
||||
return sym instanceof AST_SymbolVar
|
||||
&& !consts[sym.name]
|
||||
&& self.find_variable(sym.name) === sym.definition();
|
||||
})) return node;
|
||||
node.definitions.forEach(function(def) {
|
||||
vars.set(def.name.name, def);
|
||||
++vars_found;
|
||||
@@ -6204,6 +6211,10 @@ merge(Compressor.prototype, {
|
||||
});
|
||||
}
|
||||
if (node instanceof AST_Scope) return node;
|
||||
if (node instanceof AST_SymbolConst) {
|
||||
consts[node.name] = true;
|
||||
return node;
|
||||
}
|
||||
});
|
||||
self.transform(tt);
|
||||
if (vars_found > 0) {
|
||||
@@ -6224,48 +6235,7 @@ merge(Compressor.prototype, {
|
||||
});
|
||||
if (defs.length > 0) {
|
||||
// try to merge in assignments
|
||||
for (var i = 0; i < self.body.length;) {
|
||||
if (self.body[i] instanceof AST_SimpleStatement) {
|
||||
var expr = self.body[i].body, sym, assign;
|
||||
if (expr instanceof AST_Assign
|
||||
&& expr.operator == "="
|
||||
&& (sym = expr.left) instanceof AST_Symbol
|
||||
&& vars.has(sym.name))
|
||||
{
|
||||
var def = vars.get(sym.name);
|
||||
if (def.value) break;
|
||||
def.value = expr.right;
|
||||
remove(defs, def);
|
||||
defs.push(def);
|
||||
self.body.splice(i, 1);
|
||||
continue;
|
||||
}
|
||||
if (expr instanceof AST_Sequence
|
||||
&& (assign = expr.expressions[0]) instanceof AST_Assign
|
||||
&& assign.operator == "="
|
||||
&& (sym = assign.left) instanceof AST_Symbol
|
||||
&& vars.has(sym.name))
|
||||
{
|
||||
var def = vars.get(sym.name);
|
||||
if (def.value) break;
|
||||
def.value = assign.right;
|
||||
remove(defs, def);
|
||||
defs.push(def);
|
||||
self.body[i].body = make_sequence(expr, expr.expressions.slice(1));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (self.body[i] instanceof AST_EmptyStatement) {
|
||||
self.body.splice(i, 1);
|
||||
continue;
|
||||
}
|
||||
if (self.body[i] instanceof AST_BlockStatement) {
|
||||
var tmp = [ i, 1 ].concat(self.body[i].body);
|
||||
self.body.splice.apply(self.body, tmp);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
insert_vars(self.body);
|
||||
defs = make_node(AST_Var, self, {
|
||||
definitions: defs
|
||||
});
|
||||
@@ -6273,6 +6243,50 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
}
|
||||
self.body = dirs.concat(hoisted, self.body);
|
||||
|
||||
function insert_vars(body) {
|
||||
while (body.length) {
|
||||
var stat = body[0];
|
||||
if (stat instanceof AST_SimpleStatement) {
|
||||
var expr = stat.body, sym, assign;
|
||||
if (expr instanceof AST_Assign
|
||||
&& expr.operator == "="
|
||||
&& (sym = expr.left) instanceof AST_Symbol
|
||||
&& vars.has(sym.name)) {
|
||||
var def = vars.get(sym.name);
|
||||
if (def.value) break;
|
||||
def.value = expr.right;
|
||||
remove(defs, def);
|
||||
defs.push(def);
|
||||
body.shift();
|
||||
continue;
|
||||
}
|
||||
if (expr instanceof AST_Sequence
|
||||
&& (assign = expr.expressions[0]) instanceof AST_Assign
|
||||
&& assign.operator == "="
|
||||
&& (sym = assign.left) instanceof AST_Symbol
|
||||
&& vars.has(sym.name)) {
|
||||
var def = vars.get(sym.name);
|
||||
if (def.value) break;
|
||||
def.value = assign.right;
|
||||
remove(defs, def);
|
||||
defs.push(def);
|
||||
stat.body = make_sequence(expr, expr.expressions.slice(1));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (stat instanceof AST_EmptyStatement) {
|
||||
body.shift();
|
||||
continue;
|
||||
}
|
||||
if (stat instanceof AST_BlockStatement && !insert_vars(stat.body)) {
|
||||
body.shift();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return body.length;
|
||||
}
|
||||
});
|
||||
|
||||
function scan_local_returns(fn, transform) {
|
||||
@@ -9352,6 +9366,8 @@ merge(Compressor.prototype, {
|
||||
scope.inlined = true;
|
||||
} while (scope = scope.parent_scope);
|
||||
}
|
||||
} else if (fixed.name && fixed.name.name == "await" && is_async(fixed)) {
|
||||
single_use = false;
|
||||
}
|
||||
if (single_use) fixed.parent_scope = self.scope;
|
||||
} else if (!fixed || !fixed.is_constant_expression()) {
|
||||
|
||||
@@ -32,6 +32,54 @@ defun_name: {
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
drop_fname: {
|
||||
rename = true
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
async function await() {
|
||||
console.log("PASS");
|
||||
}
|
||||
await();
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
console.log("PASS");
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
keep_fname: {
|
||||
options = {
|
||||
keep_fnames: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
async function await() {
|
||||
console.log("PASS");
|
||||
}
|
||||
await();
|
||||
}
|
||||
expect: {
|
||||
async function await() {
|
||||
console.log("PASS");
|
||||
}
|
||||
await();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
nested_await: {
|
||||
input: {
|
||||
(async function() {
|
||||
|
||||
@@ -658,6 +658,30 @@ legacy_scope: {
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
hoist_vars: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
}
|
||||
input: {
|
||||
{
|
||||
const a = "FAIL";
|
||||
var b = 42;
|
||||
}
|
||||
var a = "PASS";
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var b;
|
||||
{
|
||||
const a = "FAIL";
|
||||
b = 42;
|
||||
}
|
||||
var a = "PASS";
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_4191: {
|
||||
options = {
|
||||
functions: true,
|
||||
|
||||
@@ -505,6 +505,24 @@ drop_fargs: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
hoist_vars: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
var [ b = 42 ] = [];
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
var [ b = 42 ] = [];
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
unused_var_1: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
|
||||
@@ -1358,6 +1358,24 @@ fn_name_unused: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
hoist_vars: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
var [ b ] = [ 42 ];
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
var [ b ] = [ 42 ];
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4280: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
|
||||
@@ -89,6 +89,31 @@ sequences_funs: {
|
||||
}
|
||||
}
|
||||
|
||||
catch_var: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
hoist_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
try {
|
||||
a;
|
||||
} catch (a) {
|
||||
var a = 0;
|
||||
a;
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2295: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
|
||||
@@ -21,9 +21,12 @@
|
||||
},
|
||||
{
|
||||
"compress": {
|
||||
"hoist_vars": true,
|
||||
"keep_infinity": true,
|
||||
"passes": 1e6,
|
||||
"unsafe": true
|
||||
},
|
||||
"keep_fnames": true,
|
||||
"toplevel": true
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user