From f101a5f3d5bc036f282c3e585401c99ed3218698 Mon Sep 17 00:00:00 2001 From: Vivek Nayyar Date: Sun, 3 Feb 2019 19:05:23 +0530 Subject: [PATCH] :rocket: code updated to take catchBlock as code block, tests updated --- .../async-await-with-try-catch.input.js | 28 +++++++- .../async-await-with-try-catch.output.js | 55 ++++++++++++-- transforms/async-await-with-try-catch.js | 71 +++++++++---------- 3 files changed, 113 insertions(+), 41 deletions(-) diff --git a/transforms/__testfixtures__/async-await-with-try-catch.input.js b/transforms/__testfixtures__/async-await-with-try-catch.input.js index 0580903..f74e1b3 100644 --- a/transforms/__testfixtures__/async-await-with-try-catch.input.js +++ b/transforms/__testfixtures__/async-await-with-try-catch.input.js @@ -25,7 +25,7 @@ async function testData() { } const a = async function(req, res) { const tasks = await repository.get(); -}; +} async function testReturnAwaitData() { return await getData(); @@ -40,3 +40,29 @@ const CompaniesController = { }); } } + +// single expression statement with no assignment to any variable +async function expressionStatement() { + a + await getSessionStatusApi(); +} + +// class method with async await +class Abc extends React.Component { + async componentDidMount() { + const b = await getData(); + } +} + +// async await inside a call expression as argument to a function +getData(async () => { + await getData(); +}) + +// jest and enzyme tests +describe('', async () => { + let translatedText = await 'dummy translation'; +}) + +describe('', async function() { + let translatedText = await 'dummy translation'; +}) diff --git a/transforms/__testfixtures__/async-await-with-try-catch.output.js b/transforms/__testfixtures__/async-await-with-try-catch.output.js index 2761258..f87801f 100644 --- a/transforms/__testfixtures__/async-await-with-try-catch.output.js +++ b/transforms/__testfixtures__/async-await-with-try-catch.output.js @@ -11,7 +11,7 @@ async function getApiData() { await getApiData(); } catch (e) { console.log(e); - }; + } } async function getQuestionsData() { @@ -36,7 +36,7 @@ async function reduce(array, reducer, accumulator) { accumulator = await reducer(accumulator, array[i], i, array); } catch (e) { console.log(e); - }; + } } return accumulator; } @@ -45,7 +45,7 @@ async function testData() { await every([2, 3], async v => (await fetch(v)).ok); } catch (e) { console.log(e); - }; + } } const a = async function(req, res) { try { @@ -53,7 +53,7 @@ const a = async function(req, res) { } catch (e) { console.log(e); } -}; +} async function testReturnAwaitData() { try { @@ -76,3 +76,50 @@ const CompaniesController = { } } } + +// single expression statement with no assignment to any variable +async function expressionStatement() { + try { + a + await getSessionStatusApi(); + } catch (e) { + console.log(e); + } +} + +// class method with async await +class Abc extends React.Component { + async componentDidMount() { + try { + const b = await getData(); + } catch (e) { + console.log(e); + } + } +} + +// async await inside a call expression as argument to a function +getData(async () => { + try { + await getData(); + } catch (e) { + console.log(e); + } +}) + +// jest and enzyme tests +describe('', async () => { + try { + let translatedText = await 'dummy translation'; + } catch (e) { + console.log(e); + } +}) + +describe('', async function() { + try { + let translatedText = await 'dummy translation'; + } catch (e) { + console.log(e); + } +}) + diff --git a/transforms/async-await-with-try-catch.js b/transforms/async-await-with-try-catch.js index ec1fcf7..a750e94 100644 --- a/transforms/async-await-with-try-catch.js +++ b/transforms/async-await-with-try-catch.js @@ -2,63 +2,62 @@ export default function transformer(file, api, options) { const j = api.jscodeshift; const root = j(file.source); - const ExpressionTypes = ['BinaryExpression', 'LogicalExpression', 'NewExpression', 'ObjectExpression']; const DisAllowedFunctionExpressionTypes = ['ArrowFunctionExpression', 'FunctionExpression', 'ObjectExpression']; function getCatchBlockExpression() { if(options.catchBlock) { - const [obj, property] = options.catchBlock.split('.'); - if(property) { - return j.callExpression(j.memberExpression(j.identifier(obj), j.identifier(property)), [ - j.identifier('e') - ]); - } else { - return j.callExpression(j.identifier(obj), [ - j.identifier('e') - ]); + try { + const astOfCatchBlockParsed = j(options.catchBlock); + let astCatchBlock = [ + j.expressionStatement( + j.callExpression(j.memberExpression(j.identifier('console'), j.identifier('log')), [j.identifier('e')]) + ) + ]; + astOfCatchBlockParsed.find(j.Program).forEach(path => { + astCatchBlock = path.node.body; + }); + return astCatchBlock; + } catch (e) { + return [ + j.expressionStatement( + j.callExpression(j.memberExpression(j.identifier('console'), j.identifier('log')), [ + j.identifier('e') + ]) + ) + ]; } } - return j.callExpression(j.memberExpression(j.identifier('console'), j.identifier('log')), [j.identifier('e')]); + return [j.expressionStatement(j.callExpression(j.memberExpression(j.identifier('console'), j.identifier('log')), [j.identifier('e')]))]; } function isAlreadyInsideTryBlock(path) { return j(path).closest(j.TryStatement).length; } + function doesNotHaveAwaitStatement(path) { + return !j(path).find(j.AwaitExpression).length; + } function replaceWithTryCatch(path, type) { - if (isAlreadyInsideTryBlock(path)) return; + if (isAlreadyInsideTryBlock(path) || doesNotHaveAwaitStatement(path)) return; j(path).replaceWith( j.tryStatement( j.blockStatement([type]), - j.catchClause(j.identifier('e'), null, j.blockStatement([j.expressionStatement(getCatchBlockExpression())])) + j.catchClause(j.identifier('e'), null, j.blockStatement(getCatchBlockExpression())) ) ); } - root.find(j.AwaitExpression).forEach(path => { - if ( - path.parent.node && - (ExpressionTypes.indexOf(path.parent.node.type) >= 0 || path.parent.node.type === 'VariableDeclarator') - ) - return; - if (path.parent.node.type === 'ReturnStatement') { + root.find(j.VariableDeclarator).forEach(path => { + if (path.node.init && DisAllowedFunctionExpressionTypes.indexOf(path.node.init.type) < 0) { replaceWithTryCatch(path.parent, path.parent.node); - } else { - replaceWithTryCatch(path, j.expressionStatement(path.node)); } }); - root.find(j.VariableDeclaration).forEach(path => { - const variableDeclarators = path.node.declarations; - variableDeclarators.forEach(variableDeclarator => { - if ( - j(variableDeclarator).find(j.AwaitExpression).length && - DisAllowedFunctionExpressionTypes.indexOf(variableDeclarator.init.type) < 0 - ) { - replaceWithTryCatch(path, path.node); - } - }); - }); - root.find(j.AssignmentExpression).forEach(path => { - if (j(path).find(j.AwaitExpression).length && DisAllowedFunctionExpressionTypes.indexOf(path.node.right.type) < 0) { - replaceWithTryCatch(path, path.parent.node); + + root.find(j.ExpressionStatement).forEach(path => { + if (path.node.expression.type !== 'CallExpression') { + replaceWithTryCatch(path, path.node); } }); + + root.find(j.ReturnStatement).forEach(path => { + replaceWithTryCatch(path, path.node); + }); return root.toSource(); }