-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
require-await.ts
79 lines (73 loc) · 2.66 KB
/
require-await.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import {
TSESTree,
AST_NODE_TYPES,
} from '@typescript-eslint/experimental-utils';
import baseRule from 'eslint/lib/rules/require-await';
import * as tsutils from 'tsutils';
import ts from 'typescript';
import * as util from '../util';
type Options = util.InferOptionsTypeFromRule<typeof baseRule>;
type MessageIds = util.InferMessageIdsTypeFromRule<typeof baseRule>;
export default util.createRule<Options, MessageIds>({
name: 'require-await',
meta: {
type: 'suggestion',
docs: {
description: 'Disallow async functions which have no `await` expression',
category: 'Best Practices',
recommended: 'error',
requiresTypeChecking: true,
},
schema: baseRule.meta.schema,
messages: baseRule.meta.messages,
},
defaultOptions: [],
create(context) {
const rules = baseRule.create(context);
const parserServices = util.getParserServices(context);
const checker = parserServices.program.getTypeChecker();
/**
* Checks if the node returns a thenable type
*
* @param {ASTNode} node - The node to check
* @returns {boolean}
*/
function isThenableType(node: ts.Node): boolean {
const type = checker.getTypeAtLocation(node);
return tsutils.isThenableType(checker, node, type);
}
return {
FunctionDeclaration: rules.FunctionDeclaration,
FunctionExpression: rules.FunctionExpression,
ArrowFunctionExpression: rules.ArrowFunctionExpression,
'ArrowFunctionExpression[async = true]'(
node: TSESTree.ArrowFunctionExpression,
): void {
// If body type is not BlockStatment, we need to check the return type here
if (node.body.type !== AST_NODE_TYPES.BlockStatement) {
const expression = parserServices.esTreeNodeToTSNodeMap.get(
node.body,
);
if (expression && isThenableType(expression)) {
// tell the base rule to mark the scope as having an await so it ignores it
rules.AwaitExpression();
}
}
},
'FunctionDeclaration:exit': rules['FunctionDeclaration:exit'],
'FunctionExpression:exit': rules['FunctionExpression:exit'],
'ArrowFunctionExpression:exit': rules['ArrowFunctionExpression:exit'],
AwaitExpression: rules.AwaitExpression,
ForOfStatement: rules.ForOfStatement,
ReturnStatement(node): void {
const { expression } = parserServices.esTreeNodeToTSNodeMap.get<
ts.ReturnStatement
>(node);
if (expression && isThenableType(expression)) {
// tell the base rule to mark the scope as having an await so it ignores it
rules.AwaitExpression();
}
},
};
},
});