Skip to content

Commit 492ee73

Browse files
committed
switch to banning general usage
1 parent 9a22040 commit 492ee73

File tree

6 files changed

+82
-195
lines changed

6 files changed

+82
-195
lines changed

.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ module.exports = {
178178
'aws-toolkits/no-console-log': 'error',
179179
'aws-toolkits/no-json-stringify-in-log': 'error',
180180
'aws-toolkits/no-printf-mismatch': 'error',
181-
'aws-toolkits/no-async-in-foreach': 'error',
181+
'aws-toolkits/no-foreach': 'error',
182182
'no-restricted-imports': [
183183
'error',
184184
{

plugins/eslint-plugin-aws-toolkits/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import NoStringExecForChildProcess from './lib/rules/no-string-exec-for-child-pr
1111
import NoConsoleLog from './lib/rules/no-console-log'
1212
import noJsonStringifyInLog from './lib/rules/no-json-stringify-in-log'
1313
import noPrintfMismatch from './lib/rules/no-printf-mismatch'
14-
import noAsyncInForEach from './lib/rules/no-async-in-foreach'
14+
import noForeach from './lib/rules/no-foreach'
1515

1616
const rules = {
1717
'no-await-on-vscode-msg': NoAwaitOnVscodeMsg,
@@ -22,7 +22,7 @@ const rules = {
2222
'no-console-log': NoConsoleLog,
2323
'no-json-stringify-in-log': noJsonStringifyInLog,
2424
'no-printf-mismatch': noPrintfMismatch,
25-
'no-async-in-foreach': noAsyncInForEach,
25+
'no-foreach': noForeach,
2626
}
2727

2828
export { rules }

plugins/eslint-plugin-aws-toolkits/lib/rules/no-async-in-foreach.ts

Lines changed: 0 additions & 149 deletions
This file was deleted.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import { ESLintUtils, TSESTree } from '@typescript-eslint/utils'
7+
import { AST_NODE_TYPES } from '@typescript-eslint/types'
8+
import { Rule } from 'eslint'
9+
10+
export const errMsg = 'Avoid using .forEach as it can lead to race conditions'
11+
12+
export default ESLintUtils.RuleCreator.withoutDocs({
13+
meta: {
14+
docs: {
15+
description: 'disallow async functions with .forEach',
16+
recommended: 'recommended',
17+
},
18+
messages: {
19+
errMsg,
20+
},
21+
type: 'problem',
22+
fixable: 'code',
23+
schema: [],
24+
},
25+
defaultOptions: [],
26+
create(context) {
27+
return {
28+
CallExpression(node: TSESTree.CallExpression) {
29+
if (
30+
node.callee.type === AST_NODE_TYPES.MemberExpression &&
31+
node.callee.property.type === AST_NODE_TYPES.Identifier &&
32+
node.callee.property.name === 'forEach' &&
33+
node.arguments.length >= 1
34+
) {
35+
return context.report({
36+
node: node,
37+
messageId: 'errMsg',
38+
})
39+
}
40+
},
41+
}
42+
},
43+
}) as unknown as Rule.RuleModule

plugins/eslint-plugin-aws-toolkits/test/rules/no-async-in-foreach.test.ts

Lines changed: 0 additions & 43 deletions
This file was deleted.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import { rules } from '../../index'
7+
import { errMsg } from '../../lib/rules/no-foreach'
8+
import { getRuleTester } from '../testUtil'
9+
10+
getRuleTester().run('no-foreach', rules['no-foreach'], {
11+
valid: ['list.map(f)', 'list.find(f)', 'list.forAll(f)', 'o.forEachItem(f)', ''],
12+
13+
invalid: [
14+
{ code: 'list.forEach((a) => await Promise.resolve(a * a))', errors: [errMsg] },
15+
{ code: 'list.forEach(async (a: any) => console.log(x))', errors: [errMsg] },
16+
{ code: 'list.forEach((a) => a.forEach(async (b) => a * b))', errors: [errMsg] },
17+
{ code: 'list.forEach(async function () {})', errors: [errMsg] },
18+
{ code: 'function f(){} \n list.forEach(f)', errors: [errMsg] },
19+
{ code: 'const f = async () => {} \n list.forEach(f)', errors: [errMsg] },
20+
{ code: 'const f = async function () {} \n list.forEach(f)', errors: [errMsg] },
21+
{ code: 'class c { \n public async f() {} \n } \n [].forEach((new c().f))', errors: [errMsg] },
22+
{
23+
code: 'class c { \n public async f() {} \n } \n const c2 = new c() \n list.forEach(c2.f)',
24+
errors: [errMsg],
25+
},
26+
{ code: 'function f() { \n return async function () {}} \n [].forEach(f())', errors: [errMsg] },
27+
{
28+
code: 'function f() { \n return new (class c { \n public async f2() {} \n })().f2 \n } \n list.forEach(f())',
29+
errors: [errMsg],
30+
},
31+
{
32+
code: 'function f() { \n return function f2() { \n return function f3() { \n return function f4() { \n return function f5() { \n return async function f6() { \n \n } \n } \n } \n } \n } \n } \n list.forEach(f()()()()())',
33+
errors: [errMsg],
34+
},
35+
],
36+
})

0 commit comments

Comments
 (0)