Skip to content

Commit 2255074

Browse files
authored
convert function to arrow form (#5907)
closes #5904
1 parent e9cf8de commit 2255074

File tree

8 files changed

+243
-71
lines changed

8 files changed

+243
-71
lines changed

Diff for: lib/compress.js

+31-32
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,19 @@ Compressor.prototype = new TreeTransformer(function(node, descend) {
210210
// output and performance.
211211
descend(node, this);
212212
var opt = node.optimize(this);
213-
if (is_scope && opt === node && !this.has_directive("use asm") && !opt.pinned()) {
214-
opt.drop_unused(this);
215-
if (opt.merge_variables(this)) opt.drop_unused(this);
216-
descend(opt, this);
213+
if (is_scope) {
214+
if (opt === node && !this.has_directive("use asm") && !opt.pinned()) {
215+
opt.drop_unused(this);
216+
if (opt.merge_variables(this)) opt.drop_unused(this);
217+
descend(opt, this);
218+
}
219+
if (this.option("arrows") && is_arrow(opt) && opt.body.length == 1) {
220+
var stat = opt.body[0];
221+
if (stat instanceof AST_Return) {
222+
opt.body.length = 0;
223+
opt.value = stat.value;
224+
}
225+
}
217226
}
218227
if (opt === node) opt._squeezed = true;
219228
return opt;
@@ -6474,29 +6483,6 @@ Compressor.prototype.compress = function(node) {
64746483
return self;
64756484
});
64766485

6477-
function opt_arrow(self, compressor) {
6478-
if (!compressor.option("arrows")) return self;
6479-
drop_rest_farg(self, compressor);
6480-
if (self.value) self.body = [ self.first_statement() ];
6481-
var body = tighten_body(self.body, compressor);
6482-
switch (body.length) {
6483-
case 1:
6484-
var stat = body[0];
6485-
if (stat instanceof AST_Return) {
6486-
self.body.length = 0;
6487-
self.value = stat.value;
6488-
break;
6489-
}
6490-
default:
6491-
self.body = body;
6492-
self.value = null;
6493-
break;
6494-
}
6495-
return self;
6496-
}
6497-
OPT(AST_Arrow, opt_arrow);
6498-
OPT(AST_AsyncArrow, opt_arrow);
6499-
65006486
OPT(AST_Function, function(self, compressor) {
65016487
drop_rest_farg(self, compressor);
65026488
self.body = tighten_body(self.body, compressor);
@@ -11138,6 +11124,19 @@ Compressor.prototype.compress = function(node) {
1113811124
return make_sequence(self, convert_args()).optimize(compressor);
1113911125
}
1114011126
}
11127+
if (compressor.option("arrows")
11128+
&& compressor.option("module")
11129+
&& (exp instanceof AST_AsyncFunction || exp instanceof AST_Function)
11130+
&& !exp.name
11131+
&& !exp.uses_arguments
11132+
&& !exp.pinned()
11133+
&& !exp.contains_this()) {
11134+
var arrow = make_node(is_async(exp) ? AST_AsyncArrow : AST_Arrow, exp, exp);
11135+
arrow.init_vars(exp.parent_scope, exp);
11136+
arrow.variables.del("arguments");
11137+
self.expression = arrow.transform(compressor);
11138+
return self;
11139+
}
1114111140
if (compressor.option("drop_console")) {
1114211141
if (exp instanceof AST_PropAccess) {
1114311142
var name = exp.expression;
@@ -14233,8 +14232,8 @@ Compressor.prototype.compress = function(node) {
1423314232
if (fn.pinned()) return;
1423414233
if (is_generator(fn)) return;
1423514234
var arrow = is_arrow(fn);
14236-
if (arrow && fn.value) return;
14237-
if (fn.body[0] instanceof AST_Directive) return;
14235+
var fn_body = arrow && fn.value ? [ fn.first_statement() ] : fn.body;
14236+
if (fn_body[0] instanceof AST_Directive) return;
1423814237
if (fn.contains_this()) return;
1423914238
if (!scope) scope = find_scope(compressor);
1424014239
var defined = new Dictionary();
@@ -14333,7 +14332,7 @@ Compressor.prototype.compress = function(node) {
1433314332
return !abort;
1433414333
};
1433514334
}
14336-
if (verify_body && !all(fn.body, verify_body)) return;
14335+
if (verify_body && !all(fn_body, verify_body)) return;
1433714336
if (!safe_from_await_yield(fn, avoid_await_yield(compressor, scope))) return;
1433814337
fn.functions.each(function(def, name) {
1433914338
scope.functions.set(name, def);
@@ -14404,7 +14403,7 @@ Compressor.prototype.compress = function(node) {
1440414403
[].unshift.apply(def.orig, orig);
1440514404
def.eliminated += orig.length;
1440614405
});
14407-
[].push.apply(body, in_loop ? fn.body.filter(function(stat) {
14406+
[].push.apply(body, in_loop ? fn_body.filter(function(stat) {
1440814407
if (!(stat instanceof AST_LambdaDefinition)) return true;
1440914408
var name = make_node(AST_SymbolVar, flatten_var(stat.name));
1441014409
var def = name.definition();
@@ -14418,7 +14417,7 @@ Compressor.prototype.compress = function(node) {
1441814417
}) ],
1441914418
}));
1442014419
return false;
14421-
}) : fn.body);
14420+
}) : fn_body);
1442214421
var inlined = make_node(AST_BlockStatement, call, { body: body });
1442314422
if (!no_return) {
1442414423
if (async) scan_local_returns(inlined, function(node) {

Diff for: test/compress/arrows.js

+90-16
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,86 @@ instanceof_lambda_4: {
749749
node_version: ">=4"
750750
}
751751

752+
func_to_arrow: {
753+
options = {
754+
arrows: true,
755+
module: true,
756+
}
757+
input: {
758+
console.log(function(a, b, c) {
759+
return b + a + c + c;
760+
}("A", "P", "S"));
761+
}
762+
expect: {
763+
console.log(((a, b, c) => b + a + c + c)("A", "P", "S"));
764+
}
765+
expect_stdout: "PASS"
766+
node_version: ">=4"
767+
}
768+
769+
func_to_arrow_var: {
770+
options = {
771+
arrows: true,
772+
module: true,
773+
reduce_vars: true,
774+
toplevel: true,
775+
unused: true,
776+
}
777+
input: {
778+
var f = function(a, b, c) {
779+
return b + a + c + c;
780+
};
781+
console.log(f("A", "P", "S"));
782+
}
783+
expect: {
784+
console.log(((a, b, c) => b + a + c + c)("A", "P", "S"));
785+
}
786+
expect_stdout: "PASS"
787+
node_version: ">=4"
788+
}
789+
790+
keep_new: {
791+
options = {
792+
arrows: true,
793+
module: true,
794+
}
795+
input: {
796+
new function(a, b, c) {
797+
console.log(b + a + c + c);
798+
}("A", "P", "S");
799+
}
800+
expect: {
801+
new function(a, b, c) {
802+
console.log(b + a + c + c);
803+
}("A", "P", "S");
804+
}
805+
expect_stdout: "PASS"
806+
node_version: ">=4"
807+
}
808+
809+
keep_new_var: {
810+
options = {
811+
arrows: true,
812+
module: true,
813+
reduce_vars: true,
814+
toplevel: true,
815+
unused: true,
816+
}
817+
input: {
818+
var f = function(a, b, c) {
819+
console.log(b + a + c + c);
820+
};
821+
new f("A", "P", "S");
822+
}
823+
expect: {
824+
new function(a, b, c) {
825+
console.log(b + a + c + c);
826+
}("A", "P", "S");
827+
}
828+
expect_stdout: "PASS"
829+
node_version: ">=4"
830+
}
831+
752832
issue_4388: {
753833
options = {
754834
inline: true,
@@ -1175,13 +1255,11 @@ issue_5416_1: {
11751255
}
11761256
expect: {
11771257
var f = () => {
1178-
{
1179-
console;
1180-
arguments = void 0,
1181-
console.log(arguments);
1182-
var arguments;
1183-
return;
1184-
}
1258+
console;
1259+
arguments = void 0,
1260+
console.log(arguments);
1261+
var arguments;
1262+
return;
11851263
};
11861264
f();
11871265
}
@@ -1210,12 +1288,10 @@ issue_5416_2: {
12101288
}
12111289
expect: {
12121290
var f = () => {
1213-
{
1214-
console;
1215-
var arguments = void 0;
1216-
for (; console.log(arguments););
1217-
return;
1218-
}
1291+
console;
1292+
var arguments = void 0;
1293+
for (; console.log(arguments););
1294+
return;
12191295
};
12201296
f();
12211297
}
@@ -1311,9 +1387,7 @@ issue_5653: {
13111387
})());
13121388
}
13131389
expect: {
1314-
console.log((a => {
1315-
return +{};
1316-
})());
1390+
console.log((a => +{})());
13171391
}
13181392
expect_stdout: "NaN"
13191393
node_version: ">=4"

Diff for: test/compress/awaits.js

+24
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,30 @@ instanceof_lambda_4: {
14071407
node_version: ">=8"
14081408
}
14091409

1410+
async_to_arrow: {
1411+
options = {
1412+
arrows: true,
1413+
module: true,
1414+
reduce_vars: true,
1415+
unused: true,
1416+
}
1417+
input: {
1418+
(async function() {
1419+
var f = async function(a, b, c) {
1420+
return b + a + c + c;
1421+
};
1422+
console.log(await f("A", "P", "S"));
1423+
})();
1424+
}
1425+
expect: {
1426+
(async () => {
1427+
console.log(await (async (a, b, c) => b + a + c + c)("A", "P", "S"));
1428+
})();
1429+
}
1430+
expect_stdout: "PASS"
1431+
node_version: ">=8"
1432+
}
1433+
14101434
issue_4335_1: {
14111435
options = {
14121436
inline: true,

Diff for: test/compress/yields.js

+55
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,61 @@ instanceof_lambda: {
970970
node_version: ">=4"
971971
}
972972

973+
keep_yield: {
974+
options = {
975+
arrows: true,
976+
module: true,
977+
}
978+
input: {
979+
console.log(function*() {
980+
yield "PASS";
981+
}().next().value);
982+
}
983+
expect: {
984+
console.log(function*() {
985+
yield "PASS";
986+
}().next().value);
987+
}
988+
expect_stdout: "PASS"
989+
node_version: ">=4"
990+
}
991+
992+
func_to_arrow_arg: {
993+
options = {
994+
arrows: true,
995+
module: true,
996+
}
997+
input: {
998+
console.log(function(yield) {
999+
return yield;
1000+
}("PASS"));
1001+
}
1002+
expect: {
1003+
console.log((yield => yield)("PASS"));
1004+
}
1005+
expect_stdout: "PASS"
1006+
node_version: ">=4"
1007+
}
1008+
1009+
func_to_arrow_var: {
1010+
options = {
1011+
arrows: true,
1012+
module: true,
1013+
}
1014+
input: {
1015+
var yield = "PASS";
1016+
console.log(function() {
1017+
return yield;
1018+
}());
1019+
}
1020+
expect: {
1021+
var yield = "PASS";
1022+
console.log((() => yield)());
1023+
}
1024+
expect_stdout: "PASS"
1025+
node_version: ">=4"
1026+
}
1027+
9731028
issue_4454_1: {
9741029
rename = false
9751030
options = {

Diff for: test/mocha/cli.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ describe("bin/uglifyjs", function() {
1616
var command = [
1717
uglifyjscmd,
1818
"--self",
19-
semver.satisfies(process.version, "<=0.12") ? "-mc hoist_funs" : "-mc",
2019
"--wrap WrappedUglifyJS",
20+
semver.satisfies(process.version, "<4") ? "--no-module" : "--module",
21+
semver.satisfies(process.version, "<=0.12") ? "-mc hoist_funs" : "-mc",
2122
].join(" ");
2223
exec(command, { maxBuffer: 1048576 }, function(err, stdout) {
2324
if (err) throw err;
@@ -61,7 +62,7 @@ describe("bin/uglifyjs", function() {
6162
"--mangle",
6263
].join(" "), function(err, stdout) {
6364
if (err) throw err;
64-
assert.strictEqual(stdout, "function(n){for(;n(););return 42}(A)\n");
65+
assert.strictEqual(stdout, "(r=>{for(;r(););return 42})(A)\n");
6566
done();
6667
}).stdin.end([
6768
"function(x) {",
@@ -1066,7 +1067,7 @@ describe("bin/uglifyjs", function() {
10661067
"return obj25.p + obj121.p + obj1024.p;",
10671068
"}());",
10681069
]).join("\n");
1069-
exec(uglifyjscmd + " -mc", function(err, stdout) {
1070+
exec(uglifyjscmd + " --no-module -mc", function(err, stdout) {
10701071
if (err) throw err;
10711072
assert.strictEqual(stdout, "console.log(function(){var p={p:25},n={p:121},o={p:1024};return p.p+n.p+o.p}());\n");
10721073
assert.strictEqual(run_code(stdout), run_code(code));

0 commit comments

Comments
 (0)