* @param hasContinuation Whether another `then`, `catch`, or `finally` continuation follows the continuation to which this callback belongs. * @param continuationArgName The argument name for the continuation that follows this call. * @param inputArgName The argument name provided
(func, hasContinuation, continuationArgName, inputArgName, parent, transformer)
| 151809 | * @param inputArgName The argument name provided to this call |
| 151810 | */ |
| 151811 | function transformCallbackArgument(func, hasContinuation, continuationArgName, inputArgName, parent, transformer) { |
| 151812 | var _a; |
| 151813 | switch (func.kind) { |
| 151814 | case 104 /* SyntaxKind.NullKeyword */: |
| 151815 | // do not produce a transformed statement for a null argument |
| 151816 | break; |
| 151817 | case 206 /* SyntaxKind.PropertyAccessExpression */: |
| 151818 | case 79 /* SyntaxKind.Identifier */: // identifier includes undefined |
| 151819 | if (!inputArgName) { |
| 151820 | // undefined was argument passed to promise handler |
| 151821 | break; |
| 151822 | } |
| 151823 | var synthCall = ts.factory.createCallExpression(ts.getSynthesizedDeepClone(func), /*typeArguments*/ undefined, isSynthIdentifier(inputArgName) ? [referenceSynthIdentifier(inputArgName)] : []); |
| 151824 | if (shouldReturn(parent, transformer)) { |
| 151825 | return maybeAnnotateAndReturn(synthCall, getExplicitPromisedTypeOfPromiseReturningCallExpression(parent, func, transformer.checker)); |
| 151826 | } |
| 151827 | var type = transformer.checker.getTypeAtLocation(func); |
| 151828 | var callSignatures = transformer.checker.getSignaturesOfType(type, 0 /* SignatureKind.Call */); |
| 151829 | if (!callSignatures.length) { |
| 151830 | // if identifier in handler has no call signatures, it's invalid |
| 151831 | return silentFail(); |
| 151832 | } |
| 151833 | var returnType = callSignatures[0].getReturnType(); |
| 151834 | var varDeclOrAssignment = createVariableOrAssignmentOrExpressionStatement(continuationArgName, ts.factory.createAwaitExpression(synthCall), getExplicitPromisedTypeOfPromiseReturningCallExpression(parent, func, transformer.checker)); |
| 151835 | if (continuationArgName) { |
| 151836 | continuationArgName.types.push(transformer.checker.getAwaitedType(returnType) || returnType); |
| 151837 | } |
| 151838 | return varDeclOrAssignment; |
| 151839 | case 213 /* SyntaxKind.FunctionExpression */: |
| 151840 | case 214 /* SyntaxKind.ArrowFunction */: { |
| 151841 | var funcBody = func.body; |
| 151842 | var returnType_1 = (_a = getLastCallSignature(transformer.checker.getTypeAtLocation(func), transformer.checker)) === null || _a === void 0 ? void 0 : _a.getReturnType(); |
| 151843 | // Arrow functions with block bodies { } will enter this control flow |
| 151844 | if (ts.isBlock(funcBody)) { |
| 151845 | var refactoredStmts = []; |
| 151846 | var seenReturnStatement = false; |
| 151847 | for (var _i = 0, _b = funcBody.statements; _i < _b.length; _i++) { |
| 151848 | var statement = _b[_i]; |
| 151849 | if (ts.isReturnStatement(statement)) { |
| 151850 | seenReturnStatement = true; |
| 151851 | if (ts.isReturnStatementWithFixablePromiseHandler(statement, transformer.checker)) { |
| 151852 | refactoredStmts = refactoredStmts.concat(transformReturnStatementWithFixablePromiseHandler(transformer, statement, hasContinuation, continuationArgName)); |
| 151853 | } |
| 151854 | else { |
| 151855 | var possiblyAwaitedRightHandSide = returnType_1 && statement.expression ? getPossiblyAwaitedRightHandSide(transformer.checker, returnType_1, statement.expression) : statement.expression; |
| 151856 | refactoredStmts.push.apply(refactoredStmts, maybeAnnotateAndReturn(possiblyAwaitedRightHandSide, getExplicitPromisedTypeOfPromiseReturningCallExpression(parent, func, transformer.checker))); |
| 151857 | } |
| 151858 | } |
| 151859 | else if (hasContinuation && ts.forEachReturnStatement(statement, ts.returnTrue)) { |
| 151860 | // If there is a nested `return` in a callback that has a trailing continuation, we don't transform it as the resulting complexity is too great. For example: |
| 151861 | // |
| 151862 | // source | result |
| 151863 | // -------------------------------------| --------------------------------------- |
| 151864 | // function f(): Promise<number> { | async function f9(): Promise<number> { |
| 151865 | // return foo().then(() => { | await foo(); |
| 151866 | // if (Math.random()) { | if (Math.random()) { |
| 151867 | // return 1; | return 1; // incorrect early return |
| 151868 | // } | } |
no test coverage detected