diff --git a/lib/compress.js b/lib/compress.js index 9e1d8232..717f931e 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -4655,4 +4655,41 @@ merge(Compressor.prototype, { OPT(AST_PrefixedTemplateString, function(self, compressor){ return self; }); + + OPT(AST_ObjectKeyVal, function(self, compressor){ + // p:function(){} ---> p(){} + // p:function*(){} ---> *p(){} + // p:async function(){} ---> async p(){} + // p:()=>{} ---> p(){} + // p:async()=>{} ---> async p(){} + if (compressor.option("ecma") >= 6) { + var key = self.key; + var value = self.value; + var is_arrow_with_block = value instanceof AST_Arrow + && Array.isArray(value.body) + && !contains_this(value); + if ((is_arrow_with_block || value instanceof AST_Function) && !value.name) { + return make_node(AST_ConciseMethod, self, { + async: value.async, + is_generator: value.is_generator, + key: key instanceof AST_Node ? key : make_node(AST_SymbolMethod, self, { + name: key, + }), + value: make_node(AST_Accessor, value, value), + }); + } + } + return self; + + function contains_this(node) { + var result; + var tw = new TreeWalker(function(node) { + if (node instanceof AST_This) { + return result = true; + } + }); + node.walk(tw); + return result; + } + }); })(); diff --git a/test/compress/arrow.js b/test/compress/arrow.js index fc19eeb5..b081fe22 100644 --- a/test/compress/arrow.js +++ b/test/compress/arrow.js @@ -313,12 +313,13 @@ issue_2105_1: { }); } expect: { - (() => { + // TODO: outer function should be an arrow function + (function() { var quux = () => { console.log("PASS"); }; return { - prop: () => { + prop() { console.log; quux(); } diff --git a/test/compress/object.js b/test/compress/object.js index 5ac9394e..52d7ad77 100644 --- a/test/compress/object.js +++ b/test/compress/object.js @@ -510,3 +510,157 @@ variable_as_computed_property: { } expect_exact: "function getLine(header){return{[header]:{}}}" } + +prop_func_to_concise_method: { + options = { + ecma: 6, + } + input: { + ({ + emit: function NamedFunctionExpression() { + console.log("PASS"); + }, + run: function() { + this.emit(); + } + }).run(); + } + expect: { + ({ + emit: function NamedFunctionExpression() { + console.log("PASS"); + }, + run() { + this.emit(); + } + }).run(); + } + expect_stdout: "PASS" + node_version: ">=6" +} + +prop_arrow_to_concise_method: { + options = { + ecma: 6, + } + input: { + ({ + run: () => { + console.log("PASS"); + } + }).run(); + } + expect: { + ({ + run() { + console.log("PASS"); + } + }).run(); + } + expect_stdout: "PASS" + node_version: ">=6" +} + +prop_func_to_async_concise_method: { + options = { + ecma: 8, + } + input: { + ({ + run: async function() { + console.log("PASS"); + } + }).run(); + } + expect: { + ({ + async run() { + console.log("PASS"); + } + }).run(); + } + expect_stdout: "PASS" + node_version: ">=8" +} + +prop_func_to_concise_method_various: { + options = { + ecma: 6, + } + input: { + ({ + null: function(x, y){ x(y); }, + 123: function(x, y){ x(y); }, + "A B": function(x, y){ x(y); }, + p1: function(x, y){ x(y); }, + p2: function*(x, y){ yield x(y); }, + p3: async function(x, y){ await x(y); }, + [c1]: function(x, y){ x(y); }, + [c2]: function*(x, y){ yield x(y); }, + [c3]: async function(x, y){ await x(y); }, + }); + } + expect: { + ({ + null(x, y) { x(y); }, + 123(x, y) { x(y); }, + "A B"(x, y) { x(y); }, + p1(x, y) { x(y); }, + *p2(x, y) { yield x(y); }, + async p3(x, y) { await x(y); }, + [c1](x, y) { x(y); }, + *[c2](x, y) { yield x(y); }, + async [c3](x, y) { await x(y); }, + }); + } +} + +prop_arrows_to_concise_method_various: { + options = { + ecma: 6, + } + input: { + ({ + null: (x, y) => { x(y); }, + 123: (x, y) => { x(y); }, + "A B": (x, y) => { x(y); }, + p1: (x, y) => { x(y); }, + p3: async (x, y) => { await x(y); }, + [c1]: (x, y) => { x(y); }, + [c3]: async (x, y) => { await x(y); }, + }); + } + expect: { + ({ + null(x, y) { x(y); }, + 123(x, y) { x(y); }, + "A B"(x, y) { x(y); }, + p1(x, y) { x(y); }, + async p3(x, y) { await x(y); }, + [c1](x, y) { x(y); }, + async [c3](x, y) { await x(y); }, + }); + } +} + +prop_arrow_with_this: { + options = { + ecma: 6, + } + input: { + ({ + func_no_this: function() { run(); }, + func_with_this: function() { run(this); }, + arrow_no_this: () => { run(); }, + arrow_with_this: () => { run(this); }, + }); + } + expect: { + ({ + func_no_this() { run(); }, + func_with_this() { run(this); }, + arrow_no_this() { run(); }, + arrow_with_this: () => { run(this); }, + }); + } +}