Skip to content

Commit

Permalink
convert function to arrow form (#5907)
Browse files Browse the repository at this point in the history
closes #5904
  • Loading branch information
alexlamsl committed Aug 6, 2024
1 parent e9cf8de commit 2255074
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 71 deletions.
63 changes: 31 additions & 32 deletions lib/compress.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,19 @@ Compressor.prototype = new TreeTransformer(function(node, descend) {
// output and performance.
descend(node, this);
var opt = node.optimize(this);
if (is_scope && opt === node && !this.has_directive("use asm") && !opt.pinned()) {
opt.drop_unused(this);
if (opt.merge_variables(this)) opt.drop_unused(this);
descend(opt, this);
if (is_scope) {
if (opt === node && !this.has_directive("use asm") && !opt.pinned()) {
opt.drop_unused(this);
if (opt.merge_variables(this)) opt.drop_unused(this);
descend(opt, this);
}
if (this.option("arrows") && is_arrow(opt) && opt.body.length == 1) {
var stat = opt.body[0];
if (stat instanceof AST_Return) {
opt.body.length = 0;
opt.value = stat.value;
}
}
}
if (opt === node) opt._squeezed = true;
return opt;
Expand Down Expand Up @@ -6474,29 +6483,6 @@ Compressor.prototype.compress = function(node) {
return self;
});

function opt_arrow(self, compressor) {
if (!compressor.option("arrows")) return self;
drop_rest_farg(self, compressor);
if (self.value) self.body = [ self.first_statement() ];
var body = tighten_body(self.body, compressor);
switch (body.length) {
case 1:
var stat = body[0];
if (stat instanceof AST_Return) {
self.body.length = 0;
self.value = stat.value;
break;
}
default:
self.body = body;
self.value = null;
break;
}
return self;
}
OPT(AST_Arrow, opt_arrow);
OPT(AST_AsyncArrow, opt_arrow);

OPT(AST_Function, function(self, compressor) {
drop_rest_farg(self, compressor);
self.body = tighten_body(self.body, compressor);
Expand Down Expand Up @@ -11138,6 +11124,19 @@ Compressor.prototype.compress = function(node) {
return make_sequence(self, convert_args()).optimize(compressor);
}
}
if (compressor.option("arrows")
&& compressor.option("module")
&& (exp instanceof AST_AsyncFunction || exp instanceof AST_Function)
&& !exp.name
&& !exp.uses_arguments
&& !exp.pinned()
&& !exp.contains_this()) {
var arrow = make_node(is_async(exp) ? AST_AsyncArrow : AST_Arrow, exp, exp);
arrow.init_vars(exp.parent_scope, exp);
arrow.variables.del("arguments");
self.expression = arrow.transform(compressor);
return self;
}
if (compressor.option("drop_console")) {
if (exp instanceof AST_PropAccess) {
var name = exp.expression;
Expand Down Expand Up @@ -14233,8 +14232,8 @@ Compressor.prototype.compress = function(node) {
if (fn.pinned()) return;
if (is_generator(fn)) return;
var arrow = is_arrow(fn);
if (arrow && fn.value) return;
if (fn.body[0] instanceof AST_Directive) return;
var fn_body = arrow && fn.value ? [ fn.first_statement() ] : fn.body;
if (fn_body[0] instanceof AST_Directive) return;
if (fn.contains_this()) return;
if (!scope) scope = find_scope(compressor);
var defined = new Dictionary();
Expand Down Expand Up @@ -14333,7 +14332,7 @@ Compressor.prototype.compress = function(node) {
return !abort;
};
}
if (verify_body && !all(fn.body, verify_body)) return;
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);
Expand Down Expand Up @@ -14404,7 +14403,7 @@ Compressor.prototype.compress = function(node) {
[].unshift.apply(def.orig, orig);
def.eliminated += orig.length;
});
[].push.apply(body, in_loop ? fn.body.filter(function(stat) {
[].push.apply(body, in_loop ? fn_body.filter(function(stat) {
if (!(stat instanceof AST_LambdaDefinition)) return true;
var name = make_node(AST_SymbolVar, flatten_var(stat.name));
var def = name.definition();
Expand All @@ -14418,7 +14417,7 @@ Compressor.prototype.compress = function(node) {
}) ],
}));
return false;
}) : fn.body);
}) : fn_body);
var inlined = make_node(AST_BlockStatement, call, { body: body });
if (!no_return) {
if (async) scan_local_returns(inlined, function(node) {
Expand Down
106 changes: 90 additions & 16 deletions test/compress/arrows.js
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,86 @@ instanceof_lambda_4: {
node_version: ">=4"
}

func_to_arrow: {
options = {
arrows: true,
module: true,
}
input: {
console.log(function(a, b, c) {
return b + a + c + c;
}("A", "P", "S"));
}
expect: {
console.log(((a, b, c) => b + a + c + c)("A", "P", "S"));
}
expect_stdout: "PASS"
node_version: ">=4"
}

func_to_arrow_var: {
options = {
arrows: true,
module: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var f = function(a, b, c) {
return b + a + c + c;
};
console.log(f("A", "P", "S"));
}
expect: {
console.log(((a, b, c) => b + a + c + c)("A", "P", "S"));
}
expect_stdout: "PASS"
node_version: ">=4"
}

keep_new: {
options = {
arrows: true,
module: true,
}
input: {
new function(a, b, c) {
console.log(b + a + c + c);
}("A", "P", "S");
}
expect: {
new function(a, b, c) {
console.log(b + a + c + c);
}("A", "P", "S");
}
expect_stdout: "PASS"
node_version: ">=4"
}

keep_new_var: {
options = {
arrows: true,
module: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var f = function(a, b, c) {
console.log(b + a + c + c);
};
new f("A", "P", "S");
}
expect: {
new function(a, b, c) {
console.log(b + a + c + c);
}("A", "P", "S");
}
expect_stdout: "PASS"
node_version: ">=4"
}

issue_4388: {
options = {
inline: true,
Expand Down Expand Up @@ -1175,13 +1255,11 @@ issue_5416_1: {
}
expect: {
var f = () => {
{
console;
arguments = void 0,
console.log(arguments);
var arguments;
return;
}
console;
arguments = void 0,
console.log(arguments);
var arguments;
return;
};
f();
}
Expand Down Expand Up @@ -1210,12 +1288,10 @@ issue_5416_2: {
}
expect: {
var f = () => {
{
console;
var arguments = void 0;
for (; console.log(arguments););
return;
}
console;
var arguments = void 0;
for (; console.log(arguments););
return;
};
f();
}
Expand Down Expand Up @@ -1311,9 +1387,7 @@ issue_5653: {
})());
}
expect: {
console.log((a => {
return +{};
})());
console.log((a => +{})());
}
expect_stdout: "NaN"
node_version: ">=4"
Expand Down
24 changes: 24 additions & 0 deletions test/compress/awaits.js
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,30 @@ instanceof_lambda_4: {
node_version: ">=8"
}

async_to_arrow: {
options = {
arrows: true,
module: true,
reduce_vars: true,
unused: true,
}
input: {
(async function() {
var f = async function(a, b, c) {
return b + a + c + c;
};
console.log(await f("A", "P", "S"));
})();
}
expect: {
(async () => {
console.log(await (async (a, b, c) => b + a + c + c)("A", "P", "S"));
})();
}
expect_stdout: "PASS"
node_version: ">=8"
}

issue_4335_1: {
options = {
inline: true,
Expand Down
55 changes: 55 additions & 0 deletions test/compress/yields.js
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,61 @@ instanceof_lambda: {
node_version: ">=4"
}

keep_yield: {
options = {
arrows: true,
module: true,
}
input: {
console.log(function*() {
yield "PASS";
}().next().value);
}
expect: {
console.log(function*() {
yield "PASS";
}().next().value);
}
expect_stdout: "PASS"
node_version: ">=4"
}

func_to_arrow_arg: {
options = {
arrows: true,
module: true,
}
input: {
console.log(function(yield) {
return yield;
}("PASS"));
}
expect: {
console.log((yield => yield)("PASS"));
}
expect_stdout: "PASS"
node_version: ">=4"
}

func_to_arrow_var: {
options = {
arrows: true,
module: true,
}
input: {
var yield = "PASS";
console.log(function() {
return yield;
}());
}
expect: {
var yield = "PASS";
console.log((() => yield)());
}
expect_stdout: "PASS"
node_version: ">=4"
}

issue_4454_1: {
rename = false
options = {
Expand Down
7 changes: 4 additions & 3 deletions test/mocha/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ describe("bin/uglifyjs", function() {
var command = [
uglifyjscmd,
"--self",
semver.satisfies(process.version, "<=0.12") ? "-mc hoist_funs" : "-mc",
"--wrap WrappedUglifyJS",
semver.satisfies(process.version, "<4") ? "--no-module" : "--module",
semver.satisfies(process.version, "<=0.12") ? "-mc hoist_funs" : "-mc",
].join(" ");
exec(command, { maxBuffer: 1048576 }, function(err, stdout) {
if (err) throw err;
Expand Down Expand Up @@ -61,7 +62,7 @@ describe("bin/uglifyjs", function() {
"--mangle",
].join(" "), function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "function(n){for(;n(););return 42}(A)\n");
assert.strictEqual(stdout, "(r=>{for(;r(););return 42})(A)\n");
done();
}).stdin.end([
"function(x) {",
Expand Down Expand Up @@ -1066,7 +1067,7 @@ describe("bin/uglifyjs", function() {
"return obj25.p + obj121.p + obj1024.p;",
"}());",
]).join("\n");
exec(uglifyjscmd + " -mc", function(err, stdout) {
exec(uglifyjscmd + " --no-module -mc", function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "console.log(function(){var p={p:25},n={p:121},o={p:1024};return p.p+n.p+o.p}());\n");
assert.strictEqual(run_code(stdout), run_code(code));
Expand Down
Loading

0 comments on commit 2255074

Please sign in to comment.