From 8a354a7cf1ca31726565aaab2b630a60da85b643 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 3 Aug 2019 12:13:44 -0400 Subject: [PATCH] Support named function expressions with test case courtesy of @honzabrecka (closes #37) --- async-to-promises.ts | 16 +++++++++------- tests/named function expression/hoisted.js | 1 + tests/named function expression/inlined.js | 1 + tests/named function expression/input.js | 12 ++++++++++++ tests/named function expression/output.js | 1 + tests/return inside try/input.js | 2 +- 6 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 tests/named function expression/hoisted.js create mode 100644 tests/named function expression/inlined.js create mode 100644 tests/named function expression/input.js create mode 100644 tests/named function expression/output.js diff --git a/async-to-promises.ts b/async-to-promises.ts index 5656124..8f8e869 100644 --- a/async-to-promises.ts +++ b/async-to-promises.ts @@ -1465,8 +1465,8 @@ export default function({ types, template, traverse, transformFromAst, version } } // Convert an expression or statement into a callable function expression - function functionize(state: PluginState, params: LVal[], expression: Expression | Statement, target: NodePath): FunctionExpression | ArrowFunctionExpression { - if (readConfigKey(state.opts, "target") === "es6") { + function functionize(state: PluginState, params: LVal[], expression: Expression | Statement, target: NodePath, id?: Identifier): FunctionExpression | ArrowFunctionExpression { + if (!id && readConfigKey(state.opts, "target") === "es6") { let newExpression = expression; if (types.isBlockStatement(newExpression) && newExpression.body.length === 1) { newExpression = newExpression.body[0]; @@ -1502,7 +1502,7 @@ export default function({ types, template, traverse, transformFromAst, version } expression = blockStatement([expression]); } expression.body = removeUnnecessaryReturnStatements(expression.body); - return types.functionExpression(undefined, params, expression); + return types.functionExpression(id, params, expression); } // Create a block statement from a list of statements @@ -3432,7 +3432,8 @@ export default function({ types, template, traverse, transformFromAst, version } types.newExpression(helperReference(this, path, "_AsyncGenerator"), [ functionize(this, [generatorIdentifier], bodyPath.node, path) ]), - path + path, + id )); } else { rewriteAsyncBlock({ state: this }, path, []); @@ -3448,8 +3449,8 @@ export default function({ types, template, traverse, transformFromAst, version } path.traverse(unwrapReturnPromiseVisitor); } if (canThrow) { - if (inlineHelpers) { - if (skipReturn && parentPath.isCallExpression() && parentPath.node.arguments.length === 0 && !pathsReturn(bodyPath).any) { + if (inlineHelpers || id) { + if (!id && skipReturn && parentPath.isCallExpression() && parentPath.node.arguments.length === 0 && !pathsReturn(bodyPath).any) { parentPath.parentPath.replaceWith( types.tryStatement( bodyPath.node, @@ -3493,6 +3494,7 @@ export default function({ types, template, traverse, transformFromAst, version } ) ), path, + id )); } } else { @@ -3505,7 +3507,7 @@ export default function({ types, template, traverse, transformFromAst, version } if (!inlineHelpers) { checkForErrorsAndRewriteReturns(bodyPath, this, true) } - path.replaceWith(functionize(this, path.node.params, bodyPath.node, path)); + path.replaceWith(functionize(this, path.node.params, bodyPath.node, path, id)); } } nodeIsAsyncMap.set(path.node, true); diff --git a/tests/named function expression/hoisted.js b/tests/named function expression/hoisted.js new file mode 100644 index 0000000..d74f03e --- /dev/null +++ b/tests/named function expression/hoisted.js @@ -0,0 +1 @@ +function(...fns){return value=>new Promise((resolve,reject)=>{function _temp3(e){reject(e);}(function run([f,...fns],value){try{function _temp2(){if(f===undefined)resolve(value);else return _await(f(value),_temp);}function _temp(_f){run(fns,_f);}return _continueIgnored(_catch(function(){return _invokeIgnored(_temp2);},_temp3));}catch(e){Promise.reject(e);}})(fns,value);});} \ No newline at end of file diff --git a/tests/named function expression/inlined.js b/tests/named function expression/inlined.js new file mode 100644 index 0000000..7cd80e3 --- /dev/null +++ b/tests/named function expression/inlined.js @@ -0,0 +1 @@ +function(...fns){return value=>new Promise((resolve,reject)=>{(function run([f,...fns],value){try{return _catch(function(){const _temp=function(){if(f===undefined)resolve(value);else return Promise.resolve(f(value)).then(function(_f){run(fns,_f);});}();if(_temp&&_temp.then)return _temp.then(function(){});},function(e){reject(e);});}catch(e){Promise.reject(e);}})(fns,value);});} \ No newline at end of file diff --git a/tests/named function expression/input.js b/tests/named function expression/input.js new file mode 100644 index 0000000..9d5fc5e --- /dev/null +++ b/tests/named function expression/input.js @@ -0,0 +1,12 @@ +function(...fns) { + return (value) => new Promise((resolve, reject) => { + (async function run([f, ...fns], value) { + try { + if (f === undefined) resolve(value) + else run(fns, await f(value)) + } catch (e) { + reject(e) + } + })(fns, value); + }); +} diff --git a/tests/named function expression/output.js b/tests/named function expression/output.js new file mode 100644 index 0000000..99a7f7b --- /dev/null +++ b/tests/named function expression/output.js @@ -0,0 +1 @@ +function(...fns){return value=>new Promise((resolve,reject)=>{(function run([f,...fns],value){try{return _continueIgnored(_catch(()=>_invokeIgnored(()=>{if(f===undefined)resolve(value);else return _await(f(value),(_f)=>{run(fns,_f);});}),e=>{reject(e);}));}catch(e){Promise.reject(e);}})(fns,value);});} \ No newline at end of file diff --git a/tests/return inside try/input.js b/tests/return inside try/input.js index 5f748a9..53d1b41 100644 --- a/tests/return inside try/input.js +++ b/tests/return inside try/input.js @@ -1,4 +1,4 @@ -async function test(wait, messages) { +async function(wait, messages) { messages.push('before-try'); try { messages.push('start-try');