66import { ESLintUtils , TSESTree } from '@typescript-eslint/utils'
77import { AST_NODE_TYPES } from '@typescript-eslint/types'
88import { Rule } from 'eslint'
9+ import { RuleContext } from '@typescript-eslint/utils/ts-eslint'
910
1011export const errMsg = 'Avoid using async methods with .forEach as it leads to race conditions'
1112
12- function isAsyncFunction ( node : TSESTree . CallExpressionArgument ) : boolean {
13+ function isAsyncFunction < T extends string , T2 extends readonly unknown [ ] > (
14+ context : RuleContext < T , T2 > ,
15+ funcNode : TSESTree . CallExpressionArgument
16+ ) {
17+ if ( funcNode . type === AST_NODE_TYPES . Identifier ) {
18+ console . log ( 'is identifier' )
19+ const scope = context . sourceCode . getScope ( funcNode )
20+ const maybeFNode =
21+ scope . variables . find ( ( v ) => v . name === funcNode . name ) ?. defs . find ( ( d ) => ! ! d ) ?. node ?? undefined
22+ console . log ( maybeFNode )
23+ if (
24+ maybeFNode &&
25+ ( maybeFNode . type === AST_NODE_TYPES . ArrowFunctionExpression ||
26+ maybeFNode . type === AST_NODE_TYPES . FunctionExpression ||
27+ maybeFNode . type === AST_NODE_TYPES . FunctionDeclaration ) &&
28+ maybeFNode . async
29+ ) {
30+ return true
31+ }
32+ return false
33+ }
1334 return (
14- ( node . type === AST_NODE_TYPES . ArrowFunctionExpression || node . type === AST_NODE_TYPES . FunctionExpression ) &&
15- node . async
35+ ( funcNode . type === AST_NODE_TYPES . ArrowFunctionExpression ||
36+ funcNode . type === AST_NODE_TYPES . FunctionExpression ) &&
37+ funcNode . async
1638 )
1739}
40+
1841export default ESLintUtils . RuleCreator . withoutDocs ( {
1942 meta : {
2043 docs : {
@@ -36,13 +59,14 @@ export default ESLintUtils.RuleCreator.withoutDocs({
3659 node . callee . type === AST_NODE_TYPES . MemberExpression &&
3760 node . callee . property . type === AST_NODE_TYPES . Identifier &&
3861 node . callee . property . name === 'forEach' &&
39- node . arguments . length >= 1 &&
40- isAsyncFunction ( node . arguments [ 0 ] )
62+ node . arguments . length >= 1
4163 ) {
42- return context . report ( {
43- node : node ,
44- messageId : 'errMsg' ,
45- } )
64+ if ( isAsyncFunction ( context , node . arguments [ 0 ] ) ) {
65+ return context . report ( {
66+ node : node ,
67+ messageId : 'errMsg' ,
68+ } )
69+ }
4670 }
4771 } ,
4872 }
0 commit comments