Skip to content

Commit f907262

Browse files
author
Benjamin Lichtman
committed
Run callback as expression statement when no arg to assign to exists
1 parent 394ee31 commit f907262

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

src/services/codefixes/convertToAsyncFunction.ts

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,7 @@ namespace ts.codefix {
234234

235235
if (renameInfo) {
236236
const type = checker.getTypeAtLocation(node);
237-
if (type) {
238-
originalType.set(getNodeId(clone).toString(), type);
239-
}
237+
originalType.set(getNodeId(clone).toString(), type);
240238
}
241239
}
242240

@@ -391,9 +389,14 @@ namespace ts.codefix {
391389
return [createReturn(getSynthesizedDeepClone(node))];
392390
}
393391

394-
function createVariableDeclarationOrAssignment(prevArgName: SynthIdentifier, rightHandSide: Expression, transformer: Transformer): NodeArray<Statement> {
392+
function createVariableDeclarationOrAssignment(prevArgName: SynthIdentifier | undefined, rightHandSide: Expression, transformer: Transformer): NodeArray<Statement> {
393+
if (!prevArgName || prevArgName.identifier.text.length === 0) {
394+
// if there's no argName to assign to, there still might be side effects
395+
return createNodeArray([createStatement(rightHandSide)]);
396+
}
395397

396398
if (prevArgName.types.length < prevArgName.numberOfAssignmentsOriginal) {
399+
// if the variable has already been declared, we don't need "let" or "const"
397400
return createNodeArray([createStatement(createAssignment(getSynthesizedDeepClone(prevArgName.identifier), rightHandSide))]);
398401
}
399402

@@ -404,29 +407,32 @@ namespace ts.codefix {
404407
// should be kept up to date with isFixablePromiseArgument in suggestionDiagnostics.ts
405408
function getTransformationBody(func: Node, prevArgName: SynthIdentifier | undefined, argName: SynthIdentifier, parent: CallExpression, transformer: Transformer): NodeArray<Statement> {
406409

407-
const hasPrevArgName = prevArgName && prevArgName.identifier.text.length > 0;
408410
const hasArgName = argName && argName.identifier.text.length > 0;
409411
const shouldReturn = transformer.setOfExpressionsToReturn.get(getNodeId(parent).toString());
410412
switch (func.kind) {
411413
case SyntaxKind.NullKeyword:
412414
// do not produce a transformed statement for a null argument
413415
break;
414-
case SyntaxKind.Identifier:
415-
// identifier includes undefined
416+
case SyntaxKind.Identifier: // identifier includes undefined
416417
if (!hasArgName) break;
417418

418419
const synthCall = createCall(getSynthesizedDeepClone(func) as Identifier, /*typeArguments*/ undefined, [argName.identifier]);
419420
if (shouldReturn) {
420421
return createNodeArray([createReturn(synthCall)]);
421422
}
422423

423-
if (!hasPrevArgName) break;
424-
425-
const type = transformer.originalTypeMap.get(getNodeId(func).toString());
426-
const callSignatures = type && transformer.checker.getSignaturesOfType(type, SignatureKind.Call);
427-
const returnType = callSignatures && callSignatures[0].getReturnType();
428-
const varDeclOrAssignment = createVariableDeclarationOrAssignment(prevArgName!, createAwait(synthCall), transformer);
429-
prevArgName!.types.push(returnType!);
424+
const type = transformer.originalTypeMap.get(getNodeId(func).toString()) || transformer.checker.getTypeAtLocation(func);
425+
const callSignatures = transformer.checker.getSignaturesOfType(type, SignatureKind.Call);
426+
if (!callSignatures.length) {
427+
// if identifier in handler has no call signatures, it's invalid
428+
codeActionSucceeded = false;
429+
break;
430+
}
431+
const returnType = callSignatures[0].getReturnType();
432+
const varDeclOrAssignment = createVariableDeclarationOrAssignment(prevArgName, createAwait(synthCall), transformer);
433+
if (prevArgName) {
434+
prevArgName.types.push(returnType);
435+
}
430436
return varDeclOrAssignment;
431437

432438
case SyntaxKind.FunctionDeclaration:
@@ -462,19 +468,21 @@ namespace ts.codefix {
462468
return createNodeArray(innerCbBody);
463469
}
464470

465-
if (hasPrevArgName && !shouldReturn) {
471+
if (!shouldReturn) {
466472
const type = transformer.checker.getTypeAtLocation(func);
467473
const returnType = getLastCallSignature(type, transformer.checker)!.getReturnType();
468-
const varDeclOrAssignment = createVariableDeclarationOrAssignment(prevArgName!, getSynthesizedDeepClone(funcBody) as Expression, transformer);
469-
prevArgName!.types.push(returnType);
474+
const varDeclOrAssignment = createVariableDeclarationOrAssignment(prevArgName, getSynthesizedDeepClone(funcBody) as Expression, transformer);
475+
if (prevArgName) {
476+
prevArgName.types.push(returnType);
477+
}
470478
return varDeclOrAssignment;
471479
}
472480
else {
473481
return createNodeArray([createReturn(getSynthesizedDeepClone(funcBody) as Expression)]);
474482
}
475483
}
476484
default:
477-
// We've found a transformation body we don't know how to handle, so the refactoring should no-op to avoid deleting code.
485+
// If no cases apply, we've found a transformation body we don't know how to handle, so the refactoring should no-op to avoid deleting code.
478486
codeActionSucceeded = false;
479487
break;
480488
}

0 commit comments

Comments
 (0)