@@ -11,6 +11,8 @@ interface ScopeInfo {
1111 upper : ScopeInfo | null ;
1212 hasAwait : boolean ;
1313 hasAsync : boolean ;
14+ isGen : boolean ;
15+ isAsyncYield : boolean ;
1416}
1517type FunctionNode =
1618 | TSESTree . FunctionDeclaration
@@ -49,6 +51,8 @@ export default util.createRule({
4951 upper : scopeInfo ,
5052 hasAwait : false ,
5153 hasAsync : node . async ,
54+ isGen : node . generator || false ,
55+ isAsyncYield : false ,
5256 } ;
5357 }
5458
@@ -62,7 +66,12 @@ export default util.createRule({
6266 return ;
6367 }
6468
65- if ( node . async && ! scopeInfo . hasAwait && ! isEmptyFunction ( node ) ) {
69+ if (
70+ node . async &&
71+ ! scopeInfo . hasAwait &&
72+ ! isEmptyFunction ( node ) &&
73+ ! ( scopeInfo . isGen && scopeInfo . isAsyncYield )
74+ ) {
6675 context . report ( {
6776 node,
6877 loc : getFunctionHeadLoc ( node , sourceCode ) ,
@@ -92,10 +101,34 @@ export default util.createRule({
92101 if ( ! scopeInfo ) {
93102 return ;
94103 }
95-
96104 scopeInfo . hasAwait = true ;
97105 }
98106
107+ /**
108+ * mark `scopeInfo.isAsyncYield` to `true` if its a generator
109+ * function and the delegate is `true`
110+ */
111+ function markAsHasDelegateGen ( node : TSESTree . YieldExpression ) : void {
112+ if ( ! scopeInfo || ! scopeInfo . isGen || ! node . argument ) {
113+ return ;
114+ }
115+
116+ if ( node ?. argument ?. type === AST_NODE_TYPES . Literal ) {
117+ // making this `false` as for literals we don't need to check the definition
118+ // eg : async function* run() { yield* 1 }
119+ scopeInfo . isAsyncYield = false ;
120+ }
121+
122+ const tsNode = parserServices . esTreeNodeToTSNodeMap . get ( node ?. argument ) ;
123+ const type = checker . getTypeAtLocation ( tsNode ) ;
124+ const symbol = type . getSymbol ( ) ;
125+
126+ // async function* test1() {yield* asyncGenerator() }
127+ if ( symbol ?. getName ( ) === 'AsyncGenerator' ) {
128+ scopeInfo . isAsyncYield = true ;
129+ }
130+ }
131+
99132 return {
100133 FunctionDeclaration : enterFunction ,
101134 FunctionExpression : enterFunction ,
@@ -106,6 +139,7 @@ export default util.createRule({
106139
107140 AwaitExpression : markAsHasAwait ,
108141 'ForOfStatement[await = true]' : markAsHasAwait ,
142+ 'YieldExpression[delegate = true]' : markAsHasDelegateGen ,
109143
110144 // check body-less async arrow function.
111145 // ignore `async () => await foo` because it's obviously correct
0 commit comments