compress empty for-in loops (#3590)
This commit is contained in:
@@ -3912,19 +3912,6 @@ merge(Compressor.prototype, {
|
|||||||
scope = save_scope;
|
scope = save_scope;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
function log(sym, text, props) {
|
|
||||||
AST_Node[sym.unreferenced() ? "warn" : "info"](text, props);
|
|
||||||
}
|
|
||||||
|
|
||||||
function template(sym) {
|
|
||||||
return {
|
|
||||||
name : sym.name,
|
|
||||||
file : sym.start.file,
|
|
||||||
line : sym.start.line,
|
|
||||||
col : sym.start.col
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}, function(node, in_list) {
|
}, function(node, in_list) {
|
||||||
if (node instanceof AST_For) {
|
if (node instanceof AST_For) {
|
||||||
// Certain combination of unused name + side effect leads to invalid AST:
|
// Certain combination of unused name + side effect leads to invalid AST:
|
||||||
@@ -3952,6 +3939,21 @@ merge(Compressor.prototype, {
|
|||||||
node.init = null;
|
node.init = null;
|
||||||
}
|
}
|
||||||
return !block ? node : in_list ? MAP.splice(block.body) : block;
|
return !block ? node : in_list ? MAP.splice(block.body) : block;
|
||||||
|
} else if (node instanceof AST_ForIn) {
|
||||||
|
if (!drop_vars || !compressor.option("loops")) return;
|
||||||
|
if (!(node.init instanceof AST_Definitions)) return;
|
||||||
|
var sym = node.init.definitions[0].name;
|
||||||
|
if (sym.definition().id in in_use_ids) return;
|
||||||
|
if (!is_empty(node.body)) return;
|
||||||
|
log(sym, "Dropping unused loop variable {name} [{file}:{line},{col}]", template(sym));
|
||||||
|
var value = node.object.drop_side_effect_free(compressor);
|
||||||
|
if (value) {
|
||||||
|
AST_Node.warn("Side effects in object of for-in loop [{file}:{line},{col}]", template(sym));
|
||||||
|
return make_node(AST_SimpleStatement, node, {
|
||||||
|
body: value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
|
||||||
} else if (node instanceof AST_Sequence) {
|
} else if (node instanceof AST_Sequence) {
|
||||||
if (node.expressions.length == 1) return node.expressions[0];
|
if (node.expressions.length == 1) return node.expressions[0];
|
||||||
}
|
}
|
||||||
@@ -3962,6 +3964,19 @@ merge(Compressor.prototype, {
|
|||||||
fn.name = null;
|
fn.name = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function log(sym, text, props) {
|
||||||
|
AST_Node[sym.unreferenced() ? "warn" : "info"](text, props);
|
||||||
|
}
|
||||||
|
|
||||||
|
function template(sym) {
|
||||||
|
return {
|
||||||
|
name: sym.name,
|
||||||
|
file: sym.start.file,
|
||||||
|
line: sym.start.line,
|
||||||
|
col : sym.start.col
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function verify_safe_usage(def, read, modified) {
|
function verify_safe_usage(def, read, modified) {
|
||||||
if (def.id in in_use_ids) return;
|
if (def.id in in_use_ids) return;
|
||||||
if (read && modified) {
|
if (read && modified) {
|
||||||
|
|||||||
@@ -689,3 +689,67 @@ step: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
empty_for_in: {
|
||||||
|
options = {
|
||||||
|
loops: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (var a in [ 1, 2, 3 ]) {
|
||||||
|
var b = a + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_warnings: [
|
||||||
|
"WARN: Dropping unused variable b [test/compress/loops.js:2,16]",
|
||||||
|
"INFO: Dropping unused loop variable a [test/compress/loops.js:1,17]",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
empty_for_in_used: {
|
||||||
|
options = {
|
||||||
|
loops: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (var a in [ 1, 2, 3 ]) {
|
||||||
|
var b = a + 1;
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var a in [ 1, 2, 3 ]);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
expect_warnings: [
|
||||||
|
"WARN: Dropping unused variable b [test/compress/loops.js:2,16]",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
empty_for_in_side_effects: {
|
||||||
|
options = {
|
||||||
|
loops: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (var a in {
|
||||||
|
foo: console.log("PASS")
|
||||||
|
}) {
|
||||||
|
var b = a + "bar";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
expect_warnings: [
|
||||||
|
"WARN: Dropping unused variable b [test/compress/loops.js:4,16]",
|
||||||
|
"INFO: Dropping unused loop variable a [test/compress/loops.js:1,17]",
|
||||||
|
"WARN: Side effects in object of for-in loop [test/compress/loops.js:1,17]",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user