@@ -11,6 +11,8 @@ interface ScopeInfo {
11
11
upper : ScopeInfo | null ;
12
12
hasAwait : boolean ;
13
13
hasAsync : boolean ;
14
+ isGen : boolean ;
15
+ isAsyncYield : boolean ;
14
16
}
15
17
type FunctionNode =
16
18
| TSESTree . FunctionDeclaration
@@ -49,6 +51,8 @@ export default util.createRule({
49
51
upper : scopeInfo ,
50
52
hasAwait : false ,
51
53
hasAsync : node . async ,
54
+ isGen : node . generator || false ,
55
+ isAsyncYield : false ,
52
56
} ;
53
57
}
54
58
@@ -62,7 +66,12 @@ export default util.createRule({
62
66
return ;
63
67
}
64
68
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
+ ) {
66
75
context . report ( {
67
76
node,
68
77
loc : getFunctionHeadLoc ( node , sourceCode ) ,
@@ -92,10 +101,34 @@ export default util.createRule({
92
101
if ( ! scopeInfo ) {
93
102
return ;
94
103
}
95
-
96
104
scopeInfo . hasAwait = true ;
97
105
}
98
106
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
+
99
132
return {
100
133
FunctionDeclaration : enterFunction ,
101
134
FunctionExpression : enterFunction ,
@@ -106,6 +139,7 @@ export default util.createRule({
106
139
107
140
AwaitExpression : markAsHasAwait ,
108
141
'ForOfStatement[await = true]' : markAsHasAwait ,
142
+ 'YieldExpression[delegate = true]' : markAsHasDelegateGen ,
109
143
110
144
// check body-less async arrow function.
111
145
// ignore `async () => await foo` because it's obviously correct
0 commit comments