1
1
import {
2
2
TSESTree ,
3
- TSESLint ,
4
3
AST_NODE_TYPES ,
5
4
} from '@typescript-eslint/experimental-utils' ;
6
5
import baseRule from 'eslint/lib/rules/require-await' ;
@@ -11,11 +10,6 @@ import * as util from '../util';
11
10
type Options = util . InferOptionsTypeFromRule < typeof baseRule > ;
12
11
type MessageIds = util . InferMessageIdsTypeFromRule < typeof baseRule > ;
13
12
14
- interface ScopeInfo {
15
- upper : ScopeInfo | null ;
16
- returnsPromise : boolean ;
17
- }
18
-
19
13
export default util . createRule < Options , MessageIds > ( {
20
14
name : 'require-await' ,
21
15
meta : {
@@ -35,82 +29,6 @@ export default util.createRule<Options, MessageIds>({
35
29
const parserServices = util . getParserServices ( context ) ;
36
30
const checker = parserServices . program . getTypeChecker ( ) ;
37
31
38
- let scopeInfo : ScopeInfo | null = null ;
39
-
40
- /**
41
- * Push the scope info object to the stack.
42
- *
43
- * @returns {void }
44
- */
45
- function enterFunction (
46
- node :
47
- | TSESTree . FunctionDeclaration
48
- | TSESTree . FunctionExpression
49
- | TSESTree . ArrowFunctionExpression ,
50
- ) : void {
51
- scopeInfo = {
52
- upper : scopeInfo ,
53
- returnsPromise : false ,
54
- } ;
55
-
56
- switch ( node . type ) {
57
- case AST_NODE_TYPES . FunctionDeclaration :
58
- rules . FunctionDeclaration ( node ) ;
59
- break ;
60
-
61
- case AST_NODE_TYPES . FunctionExpression :
62
- rules . FunctionExpression ( node ) ;
63
- break ;
64
-
65
- case AST_NODE_TYPES . ArrowFunctionExpression :
66
- rules . ArrowFunctionExpression ( node ) ;
67
-
68
- // If body type is not BlockStatment, we need to check the return type here
69
- if ( node . body . type !== AST_NODE_TYPES . BlockStatement ) {
70
- const expression = parserServices . esTreeNodeToTSNodeMap . get (
71
- node . body ,
72
- ) ;
73
- scopeInfo . returnsPromise = isThenableType ( expression ) ;
74
- }
75
-
76
- break ;
77
- }
78
- }
79
-
80
- /**
81
- * Pop the top scope info object from the stack.
82
- * Passes through to the base rule if the function doesn't return a promise
83
- *
84
- * @param {ASTNode } node - The node exiting
85
- * @returns {void }
86
- */
87
- function exitFunction (
88
- node :
89
- | TSESTree . FunctionDeclaration
90
- | TSESTree . FunctionExpression
91
- | TSESTree . ArrowFunctionExpression ,
92
- ) : void {
93
- if ( scopeInfo ) {
94
- if ( ! scopeInfo . returnsPromise ) {
95
- switch ( node . type ) {
96
- case AST_NODE_TYPES . FunctionDeclaration :
97
- rules [ 'FunctionDeclaration:exit' ] ( node ) ;
98
- break ;
99
-
100
- case AST_NODE_TYPES . FunctionExpression :
101
- rules [ 'FunctionExpression:exit' ] ( node ) ;
102
- break ;
103
-
104
- case AST_NODE_TYPES . ArrowFunctionExpression :
105
- rules [ 'ArrowFunctionExpression:exit' ] ( node ) ;
106
- break ;
107
- }
108
- }
109
-
110
- scopeInfo = scopeInfo . upper ;
111
- }
112
- }
113
-
114
32
/**
115
33
* Checks if the node returns a thenable type
116
34
*
@@ -124,34 +42,41 @@ export default util.createRule<Options, MessageIds>({
124
42
}
125
43
126
44
return {
127
- 'FunctionDeclaration[async = true]' : enterFunction ,
128
- 'FunctionExpression[async = true]' : enterFunction ,
129
- 'ArrowFunctionExpression[async = true]' : enterFunction ,
130
- 'FunctionDeclaration[async = true]:exit' : exitFunction ,
131
- 'FunctionExpression[async = true]:exit' : exitFunction ,
132
- 'ArrowFunctionExpression[async = true]:exit' : exitFunction ,
133
-
134
- ReturnStatement ( node ) : void {
135
- if ( ! scopeInfo ) {
136
- return ;
45
+ 'FunctionDeclaration[async = true]' : rules . FunctionDeclaration ,
46
+ 'FunctionExpression[async = true]' : rules . FunctionExpression ,
47
+ 'ArrowFunctionExpression[async = true]' (
48
+ node : TSESTree . ArrowFunctionExpression ,
49
+ ) : void {
50
+ rules . ArrowFunctionExpression ( node ) ;
51
+
52
+ // If body type is not BlockStatment, we need to check the return type here
53
+ if ( node . body . type !== AST_NODE_TYPES . BlockStatement ) {
54
+ const expression = parserServices . esTreeNodeToTSNodeMap . get (
55
+ node . body ,
56
+ ) ;
57
+ if ( expression && isThenableType ( expression ) ) {
58
+ // tell the base rule to mark the scope as having an await so it ignores it
59
+ rules . AwaitExpression ( node as never ) ;
60
+ }
137
61
}
62
+ } ,
63
+ 'FunctionDeclaration[async = true]:exit' :
64
+ rules [ 'FunctionDeclaration:exit' ] ,
65
+ 'FunctionExpression[async = true]:exit' : rules [ 'FunctionExpression:exit' ] ,
66
+ 'ArrowFunctionExpression[async = true]:exit' :
67
+ rules [ 'ArrowFunctionExpression:exit' ] ,
68
+ AwaitExpression : rules . AwaitExpression ,
69
+ ForOfStatement : rules . ForOfStatement ,
138
70
71
+ ReturnStatement ( node ) : void {
139
72
const { expression } = parserServices . esTreeNodeToTSNodeMap . get <
140
73
ts . ReturnStatement
141
74
> ( node ) ;
142
- if ( ! expression ) {
143
- return ;
75
+ if ( expression && isThenableType ( expression ) ) {
76
+ // tell the base rule to mark the scope as having an await so it ignores it
77
+ rules . AwaitExpression ( node as never ) ;
144
78
}
145
-
146
- scopeInfo . returnsPromise = isThenableType ( expression ) ;
147
79
} ,
148
-
149
- AwaitExpression : rules . AwaitExpression as TSESLint . RuleFunction <
150
- TSESTree . Node
151
- > ,
152
- ForOfStatement : rules . ForOfStatement as TSESLint . RuleFunction <
153
- TSESTree . Node
154
- > ,
155
80
} ;
156
81
} ,
157
82
} ) ;
0 commit comments