fix corner cases in functions (#3372)

fixes #3371
This commit is contained in:
Alex Lam S.L
2019-04-21 02:16:05 +08:00
committed by GitHub
parent 855964a87a
commit c719552317
3 changed files with 80 additions and 10 deletions

View File

@@ -114,7 +114,7 @@ function Compressor(options, false_by_default) {
}; };
} else if (Array.isArray(pure_funcs)) { } else if (Array.isArray(pure_funcs)) {
this.pure_funcs = function(node) { this.pure_funcs = function(node) {
return pure_funcs.indexOf(node.expression.print_to_string()) < 0; return !member(node.expression.print_to_string(), pure_funcs);
}; };
} else { } else {
this.pure_funcs = return_true; this.pure_funcs = return_true;
@@ -131,7 +131,7 @@ function Compressor(options, false_by_default) {
top_retain = top_retain.split(/,/); top_retain = top_retain.split(/,/);
} }
this.top_retain = function(def) { this.top_retain = function(def) {
return top_retain.indexOf(def.name) >= 0; return member(def.name, top_retain);
}; };
} }
var toplevel = this.options["toplevel"]; var toplevel = this.options["toplevel"];
@@ -1711,7 +1711,7 @@ merge(Compressor.prototype, {
CHANGED = true; CHANGED = true;
statements.splice(i, 1); statements.splice(i, 1);
} else if (stat instanceof AST_Directive) { } else if (stat instanceof AST_Directive) {
if (seen_dirs.indexOf(stat.value) < 0) { if (!member(stat.value, seen_dirs)) {
i++; i++;
seen_dirs.push(stat.value); seen_dirs.push(stat.value);
} else { } else {
@@ -2853,7 +2853,7 @@ merge(Compressor.prototype, {
var fixed = this.fixed_value(); var fixed = this.fixed_value();
if (!fixed) return this; if (!fixed) return this;
var value; var value;
if (cached.indexOf(fixed) >= 0) { if (member(fixed, cached)) {
value = fixed._eval(); value = fixed._eval();
} else { } else {
this._eval = return_this; this._eval = return_this;
@@ -3638,11 +3638,16 @@ merge(Compressor.prototype, {
var defun = make_node(AST_Defun, def, def.value); var defun = make_node(AST_Defun, def, def.value);
defun.name = make_node(AST_SymbolDefun, def.name, def.name); defun.name = make_node(AST_SymbolDefun, def.name, def.name);
var name_def = def.name.scope.resolve().def_function(defun.name); var name_def = def.name.scope.resolve().def_function(defun.name);
if (def.value.name) def.value.name.definition().references.forEach(function(ref) { if (def.value.name) {
ref.name = name_def.name; var old_def = def.value.name.definition();
ref.thedef = name_def; def.value.walk(new TreeWalker(function(node) {
ref.reference({}); if (node instanceof AST_SymbolRef && node.definition() === old_def) {
}); node.name = name_def.name;
node.thedef = name_def;
node.reference({});
}
}));
}
body.push(defun); body.push(defun);
} else { } else {
if (side_effects.length > 0) { if (side_effects.length > 0) {
@@ -3703,6 +3708,7 @@ merge(Compressor.prototype, {
// https://github.com/mishoo/UglifyJS2/issues/44 // https://github.com/mishoo/UglifyJS2/issues/44
// https://github.com/mishoo/UglifyJS2/issues/1830 // https://github.com/mishoo/UglifyJS2/issues/1830
// https://github.com/mishoo/UglifyJS2/issues/1838 // https://github.com/mishoo/UglifyJS2/issues/1838
// https://github.com/mishoo/UglifyJS2/issues/3371
// that's an invalid AST. // that's an invalid AST.
// We fix it at this stage by moving the `var` outside the `for`. // We fix it at this stage by moving the `var` outside the `for`.
if (node instanceof AST_For) { if (node instanceof AST_For) {
@@ -3713,7 +3719,15 @@ merge(Compressor.prototype, {
node.init = block.body.pop(); node.init = block.body.pop();
block.body.push(node); block.body.push(node);
} }
if (node.init instanceof AST_SimpleStatement) { if (node.init instanceof AST_Defun) {
if (!block) {
block = make_node(AST_BlockStatement, node, {
body: [ node ]
});
}
block.body.splice(-1, 0, node.init);
node.init = null;
} else if (node.init instanceof AST_SimpleStatement) {
node.init = node.init.body; node.init = node.init.body;
} else if (is_empty(node.init)) { } else if (is_empty(node.init)) {
node.init = null; node.init = null;

View File

@@ -3012,3 +3012,32 @@ issue_3366: {
} }
expect_stdout: "PASS" expect_stdout: "PASS"
} }
issue_3371: {
options = {
functions: true,
inline: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
(function() {
var a = function f() {
(function() {
console.log(typeof f);
})();
};
while (a());
})();
}
expect: {
(function() {
function a() {
console.log(typeof a);
}
while (a());
})();
}
expect_stdout: "function"
}

View File

@@ -646,3 +646,30 @@ issue_2904: {
} }
expect_stdout: "1" expect_stdout: "1"
} }
issue_3371: {
options = {
functions: true,
join_vars: true,
loops: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
var a = function() {
console.log("PASS");
};
while (a());
})();
}
expect: {
(function() {
function a() {
console.log("PASS");
}
for (; a(); );
})();
}
expect_stdout: "PASS"
}