@@ -113,59 +113,41 @@ namespace ts {
113
113
}
114
114
}
115
115
116
- function addConvertToAsyncFunctionDiagnostics ( node : FunctionLikeDeclaration , checker : TypeChecker , diags : DiagnosticWithLocation [ ] ) : void {
117
-
118
- if ( isAsyncFunction ( node ) || ! node . body ) {
119
- return ;
116
+ function addConvertToAsyncFunctionDiagnostics ( node : FunctionLikeDeclaration , checker : TypeChecker , diags : Push < DiagnosticWithLocation > ) : void {
117
+ if ( ! isAsyncFunction ( node ) &&
118
+ node . body &&
119
+ isBlock ( node . body ) &&
120
+ hasReturnStatementWithPromiseHandler ( node . body ) &&
121
+ returnsPromise ( node , checker ) ) {
122
+ diags . push ( createDiagnosticForNode (
123
+ ! node . name && isVariableDeclaration ( node . parent ) && isIdentifier ( node . parent . name ) ? node . parent . name : node ,
124
+ Diagnostics . This_may_be_converted_to_an_async_function ) ) ;
120
125
}
126
+ }
121
127
128
+ function returnsPromise ( node : FunctionLikeDeclaration , checker : TypeChecker ) : boolean {
122
129
const functionType = checker . getTypeAtLocation ( node ) ;
123
-
124
130
const callSignatures = checker . getSignaturesOfType ( functionType , SignatureKind . Call ) ;
125
131
const returnType = callSignatures . length ? checker . getReturnTypeOfSignature ( callSignatures [ 0 ] ) : undefined ;
126
-
127
- if ( ! returnType || ! checker . getPromisedTypeOfPromise ( returnType ) ) {
128
- return ;
129
- }
130
-
131
- // collect all the return statements
132
- // check that a property access expression exists in there and that it is a handler
133
- const returnStatements = getReturnStatementsWithPromiseHandlers ( node ) ;
134
- if ( returnStatements . length > 0 ) {
135
- diags . push ( createDiagnosticForNode ( ! node . name && isVariableDeclaration ( node . parent ) && isIdentifier ( node . parent . name ) ? node . parent . name : node , Diagnostics . This_may_be_converted_to_an_async_function ) ) ;
136
- }
132
+ return ! ! returnType && ! ! checker . getPromisedTypeOfPromise ( returnType ) ;
137
133
}
138
134
139
135
function getErrorNodeFromCommonJsIndicator ( commonJsModuleIndicator : Node ) : Node {
140
136
return isBinaryExpression ( commonJsModuleIndicator ) ? commonJsModuleIndicator . left : commonJsModuleIndicator ;
141
137
}
142
138
143
- /** @internal */
144
- export function getReturnStatementsWithPromiseHandlers ( node : Node ) : ReturnStatement [ ] {
145
- const returnStatements : ReturnStatement [ ] = [ ] ;
146
- if ( isFunctionLike ( node ) ) {
147
- forEachChild ( node , visit ) ;
148
- }
149
- else {
150
- visit ( node ) ;
151
- }
152
-
153
- function visit ( child : Node ) {
154
- if ( isFunctionLike ( child ) ) {
155
- return ;
156
- }
157
-
158
- if ( isReturnStatement ( child ) && child . expression && isFixablePromiseHandler ( child . expression ) ) {
159
- returnStatements . push ( child ) ;
160
- }
139
+ function hasReturnStatementWithPromiseHandler ( body : Block ) : boolean {
140
+ return ! ! forEachReturnStatement ( body , isReturnStatementWithFixablePromiseHandler ) ;
141
+ }
161
142
162
- forEachChild ( child , visit ) ;
163
- }
164
- return returnStatements ;
143
+ /* @internal */
144
+ export function isReturnStatementWithFixablePromiseHandler ( node : Node ) : node is ReturnStatement {
145
+ return isReturnStatement ( node ) && ! ! node . expression && isFixablePromiseHandler ( node . expression ) ;
165
146
}
166
147
167
148
// Should be kept up to date with transformExpression in convertToAsyncFunction.ts
168
- function isFixablePromiseHandler ( node : Node ) : boolean {
149
+ /* @internal */
150
+ export function isFixablePromiseHandler ( node : Node ) : boolean {
169
151
// ensure outermost call exists and is a promise handler
170
152
if ( ! isPromiseHandler ( node ) || ! node . arguments . every ( isFixablePromiseArgument ) ) {
171
153
return false ;
0 commit comments