Skip to content

Commit

Permalink
fix(eslint-plugin): [return-await] handle nested functions correctly (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelBelousov committed Jul 31, 2021
1 parent f5a6806 commit 4a196b5
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 7 deletions.
26 changes: 19 additions & 7 deletions packages/eslint-plugin/src/rules/return-await.ts
Expand Up @@ -7,15 +7,16 @@ import * as tsutils from 'tsutils';
import * as ts from 'typescript';
import * as util from '../util';

interface ScopeInfo {
hasAsync: boolean;
}

type FunctionNode =
| TSESTree.FunctionDeclaration
| TSESTree.FunctionExpression
| TSESTree.ArrowFunctionExpression;

interface ScopeInfo {
hasAsync: boolean;
owningFunc: FunctionNode;
}

export default util.createRule({
name: 'return-await',
meta: {
Expand Down Expand Up @@ -49,12 +50,17 @@ export default util.createRule({
const checker = parserServices.program.getTypeChecker();
const sourceCode = context.getSourceCode();

let scopeInfo: ScopeInfo | null = null;
const scopeInfoStack: ScopeInfo[] = [];

function enterFunction(node: FunctionNode): void {
scopeInfo = {
scopeInfoStack.push({
hasAsync: node.async,
};
owningFunc: node,
});
}

function exitFunction(): void {
scopeInfoStack.pop();
}

function inTry(node: ts.Node): boolean {
Expand Down Expand Up @@ -263,6 +269,11 @@ export default util.createRule({
FunctionExpression: enterFunction,
ArrowFunctionExpression: enterFunction,

'FunctionDeclaration:exit': exitFunction,
'FunctionExpression:exit': exitFunction,
'ArrowFunctionExpression:exit': exitFunction,

// executes after less specific handler, so exitFunction is called
'ArrowFunctionExpression[async = true]:exit'(
node: TSESTree.ArrowFunctionExpression,
): void {
Expand All @@ -274,6 +285,7 @@ export default util.createRule({
}
},
ReturnStatement(node): void {
const scopeInfo = scopeInfoStack[scopeInfoStack.length - 1];
if (!scopeInfo || !scopeInfo.hasAsync || !node.argument) {
return;
}
Expand Down
53 changes: 53 additions & 0 deletions packages/eslint-plugin/tests/rules/return-await.test.ts
Expand Up @@ -232,6 +232,21 @@ ruleTester.run('return-await', rule, {
}
`,
},
{
code: `
async function test() {
const res = await Promise.resolve('{}');
try {
async function nested() {
return Promise.resolve('ok');
}
return await nested();
} catch (error) {
return await Promise.resolve('error');
}
}
`,
},
],
invalid: [
{
Expand Down Expand Up @@ -827,5 +842,43 @@ const buzz = async () => ((await foo()) ? 1 : await bar());
},
],
},
{
code: `
async function test() {
try {
const callback1 = function () {};
const callback2 = async function () {};
function callback3() {}
async function callback4() {}
const callback5 = () => {};
const callback6 = async () => {};
return Promise.resolve('try');
} finally {
return Promise.resolve('finally');
}
}
`,
output: `
async function test() {
try {
const callback1 = function () {};
const callback2 = async function () {};
function callback3() {}
async function callback4() {}
const callback5 = () => {};
const callback6 = async () => {};
return await Promise.resolve('try');
} finally {
return Promise.resolve('finally');
}
}
`,
errors: [
{
line: 10,
messageId: 'requiredPromiseAwait',
},
],
},
],
});

0 comments on commit 4a196b5

Please sign in to comment.