@@ -60,13 +60,11 @@ export default util.createRule<Options, MessageId>({
60
60
61
61
return {
62
62
ExpressionStatement ( node ) : void {
63
- const { expression } = parserServices . esTreeNodeToTSNodeMap . get ( node ) ;
64
-
65
63
if ( options . ignoreIIFE && isAsyncIife ( node ) ) {
66
64
return ;
67
65
}
68
66
69
- if ( isUnhandledPromise ( checker , expression ) ) {
67
+ if ( isUnhandledPromise ( checker , node . expression ) ) {
70
68
if ( options . ignoreVoid ) {
71
69
context . report ( {
72
70
node,
@@ -107,52 +105,52 @@ export default util.createRule<Options, MessageId>({
107
105
108
106
function isUnhandledPromise (
109
107
checker : ts . TypeChecker ,
110
- node : ts . Node ,
108
+ node : TSESTree . Node ,
111
109
) : boolean {
112
110
// First, check expressions whose resulting types may not be promise-like
113
- if (
114
- ts . isBinaryExpression ( node ) &&
115
- node . operatorToken . kind === ts . SyntaxKind . CommaToken
116
- ) {
111
+ if ( node . type === AST_NODE_TYPES . SequenceExpression ) {
117
112
// Any child in a comma expression could return a potentially unhandled
118
113
// promise, so we check them all regardless of whether the final returned
119
114
// value is promise-like.
120
- return (
121
- isUnhandledPromise ( checker , node . left ) ||
122
- isUnhandledPromise ( checker , node . right )
123
- ) ;
115
+ return node . expressions . some ( item => isUnhandledPromise ( checker , item ) ) ;
124
116
}
125
117
126
- if ( ts . isVoidExpression ( node ) && ! options . ignoreVoid ) {
118
+ if (
119
+ ! options . ignoreVoid &&
120
+ node . type === AST_NODE_TYPES . UnaryExpression &&
121
+ node . operator === 'void'
122
+ ) {
127
123
// Similarly, a `void` expression always returns undefined, so we need to
128
124
// see what's inside it without checking the type of the overall expression.
129
- return isUnhandledPromise ( checker , node . expression ) ;
125
+ return isUnhandledPromise ( checker , node . argument ) ;
130
126
}
131
127
132
128
// Check the type. At this point it can't be unhandled if it isn't a promise
133
- if ( ! isPromiseLike ( checker , node ) ) {
129
+ if (
130
+ ! isPromiseLike ( checker , parserServices . esTreeNodeToTSNodeMap . get ( node ) )
131
+ ) {
134
132
return false ;
135
133
}
136
134
137
- if ( ts . isCallExpression ( node ) ) {
135
+ if ( node . type === AST_NODE_TYPES . CallExpression ) {
138
136
// If the outer expression is a call, it must be either a `.then()` or
139
137
// `.catch()` that handles the promise.
140
138
return (
141
139
! isPromiseCatchCallWithHandler ( node ) &&
142
140
! isPromiseThenCallWithRejectionHandler ( node ) &&
143
141
! isPromiseFinallyCallWithHandler ( node )
144
142
) ;
145
- } else if ( ts . isConditionalExpression ( node ) ) {
143
+ } else if ( node . type === AST_NODE_TYPES . ConditionalExpression ) {
146
144
// We must be getting the promise-like value from one of the branches of the
147
145
// ternary. Check them directly.
148
146
return (
149
- isUnhandledPromise ( checker , node . whenFalse ) ||
150
- isUnhandledPromise ( checker , node . whenTrue )
147
+ isUnhandledPromise ( checker , node . alternate ) ||
148
+ isUnhandledPromise ( checker , node . consequent )
151
149
) ;
152
150
} else if (
153
- ts . isPropertyAccessExpression ( node ) ||
154
- ts . isIdentifier ( node ) ||
155
- ts . isNewExpression ( node )
151
+ node . type === AST_NODE_TYPES . MemberExpression ||
152
+ node . type === AST_NODE_TYPES . Identifier ||
153
+ node . type === AST_NODE_TYPES . NewExpression
156
154
) {
157
155
// If it is just a property access chain or a `new` call (e.g. `foo.bar` or
158
156
// `new Promise()`), the promise is not handled because it doesn't have the
@@ -225,30 +223,35 @@ function isFunctionParam(
225
223
return false ;
226
224
}
227
225
228
- function isPromiseCatchCallWithHandler ( expression : ts . CallExpression ) : boolean {
226
+ function isPromiseCatchCallWithHandler (
227
+ expression : TSESTree . CallExpression ,
228
+ ) : boolean {
229
229
return (
230
- ts . isPropertyAccessExpression ( expression . expression ) &&
231
- expression . expression . name . text === 'catch' &&
230
+ expression . callee . type === AST_NODE_TYPES . MemberExpression &&
231
+ expression . callee . property . type === AST_NODE_TYPES . Identifier &&
232
+ expression . callee . property . name === 'catch' &&
232
233
expression . arguments . length >= 1
233
234
) ;
234
235
}
235
236
236
237
function isPromiseThenCallWithRejectionHandler (
237
- expression : ts . CallExpression ,
238
+ expression : TSESTree . CallExpression ,
238
239
) : boolean {
239
240
return (
240
- ts . isPropertyAccessExpression ( expression . expression ) &&
241
- expression . expression . name . text === 'then' &&
241
+ expression . callee . type === AST_NODE_TYPES . MemberExpression &&
242
+ expression . callee . property . type === AST_NODE_TYPES . Identifier &&
243
+ expression . callee . property . name === 'then' &&
242
244
expression . arguments . length >= 2
243
245
) ;
244
246
}
245
247
246
248
function isPromiseFinallyCallWithHandler (
247
- expression : ts . CallExpression ,
249
+ expression : TSESTree . CallExpression ,
248
250
) : boolean {
249
251
return (
250
- ts . isPropertyAccessExpression ( expression . expression ) &&
251
- expression . expression . name . text === 'finally' &&
252
+ expression . callee . type === AST_NODE_TYPES . MemberExpression &&
253
+ expression . callee . property . type === AST_NODE_TYPES . Identifier &&
254
+ expression . callee . property . name === 'finally' &&
252
255
expression . arguments . length >= 1
253
256
) ;
254
257
}
0 commit comments