Skip to content

fix(eslint-plugin): [require-await] handle async generators #1782

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Mar 31, 2020
38 changes: 36 additions & 2 deletions packages/eslint-plugin/src/rules/require-await.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ interface ScopeInfo {
upper: ScopeInfo | null;
hasAwait: boolean;
hasAsync: boolean;
isGen: boolean;
isAsyncYield: boolean;
}
type FunctionNode =
| TSESTree.FunctionDeclaration
Expand Down Expand Up @@ -49,6 +51,8 @@ export default util.createRule({
upper: scopeInfo,
hasAwait: false,
hasAsync: node.async,
isGen: node.generator || false,
isAsyncYield: false,
};
}

Expand All @@ -62,7 +66,12 @@ export default util.createRule({
return;
}

if (node.async && !scopeInfo.hasAwait && !isEmptyFunction(node)) {
if (
node.async &&
!scopeInfo.hasAwait &&
!isEmptyFunction(node) &&
!(scopeInfo.isGen && scopeInfo.isAsyncYield)
) {
context.report({
node,
loc: getFunctionHeadLoc(node, sourceCode),
Expand Down Expand Up @@ -92,10 +101,34 @@ export default util.createRule({
if (!scopeInfo) {
return;
}

scopeInfo.hasAwait = true;
}

/**
* mark `scopeInfo.isAsyncYield` to `true` if its a generator
* function and the delegate is `true`
*/
function markAsHasDelegateGen(node: TSESTree.YieldExpression): void {
if (!scopeInfo || !scopeInfo.isGen || !node.argument) {
return;
}

if (node?.argument?.type === AST_NODE_TYPES.Literal) {
// making this `false` as for literals we don't need to check the definition
// eg : async function* run() { yield* 1 }
scopeInfo.isAsyncYield = false;
}

const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node?.argument);
const type = checker.getTypeAtLocation(tsNode);
const symbol = type.getSymbol();

// async function* test1() {yield* asyncGenerator() }
if (symbol?.getName() === 'AsyncGenerator') {
scopeInfo.isAsyncYield = true;
}
}

return {
FunctionDeclaration: enterFunction,
FunctionExpression: enterFunction,
Expand All @@ -106,6 +139,7 @@ export default util.createRule({

AwaitExpression: markAsHasAwait,
'ForOfStatement[await = true]': markAsHasAwait,
'YieldExpression[delegate = true]': markAsHasDelegateGen,

// check body-less async arrow function.
// ignore `async () => await foo` because it's obviously correct
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy