Skip to content

Commit 5f563c9

Browse files
author
Andy
authored
convertToAsyncFunction: Use ReadonlyArray / ReadonlyMap where possible (#27190)
1 parent 928bff9 commit 5f563c9

File tree

1 file changed

+40
-40
lines changed

1 file changed

+40
-40
lines changed

src/services/codefixes/convertToAsyncFunction.ts

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,24 @@ namespace ts.codefix {
1515
});
1616

1717
interface SynthIdentifier {
18-
identifier: Identifier;
19-
types: Type[];
18+
readonly identifier: Identifier;
19+
readonly types: Type[];
2020
numberOfAssignmentsOriginal: number; // number of times the variable should be assigned in the refactor
2121
}
2222

2323
interface SymbolAndIdentifier {
24-
identifier: Identifier;
25-
symbol: Symbol;
24+
readonly identifier: Identifier;
25+
readonly symbol: Symbol;
2626
}
2727

2828
interface Transformer {
29-
checker: TypeChecker;
30-
synthNamesMap: Map<SynthIdentifier>; // keys are the symbol id of the identifier
31-
allVarNames: SymbolAndIdentifier[];
32-
setOfExpressionsToReturn: Map<true>; // keys are the node ids of the expressions
33-
constIdentifiers: Identifier[];
34-
originalTypeMap: Map<Type>; // keys are the node id of the identifier
35-
isInJSFile: boolean;
29+
readonly checker: TypeChecker;
30+
readonly synthNamesMap: Map<SynthIdentifier>; // keys are the symbol id of the identifier
31+
readonly allVarNames: ReadonlyArray<SymbolAndIdentifier>;
32+
readonly setOfExpressionsToReturn: ReadonlyMap<true>; // keys are the node ids of the expressions
33+
readonly constIdentifiers: Identifier[];
34+
readonly originalTypeMap: ReadonlyMap<Type>; // keys are the node id of the identifier
35+
readonly isInJSFile: boolean;
3636
}
3737

3838
function convertToAsyncFunction(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker, context: CodeFixContextBase): void {
@@ -61,7 +61,7 @@ namespace ts.codefix {
6161
const functionToConvertRenamed: FunctionLikeDeclaration = renameCollidingVarNames(functionToConvert, checker, synthNamesMap, context, setOfExpressionsToReturn, originalTypeMap, allVarNames);
6262
const constIdentifiers = getConstIdentifiers(synthNamesMap);
6363
const returnStatements = getReturnStatementsWithPromiseHandlers(functionToConvertRenamed);
64-
const transformer = { checker, synthNamesMap, allVarNames, setOfExpressionsToReturn, constIdentifiers, originalTypeMap, isInJSFile: isInJavascript };
64+
const transformer: Transformer = { checker, synthNamesMap, allVarNames, setOfExpressionsToReturn, constIdentifiers, originalTypeMap, isInJSFile: isInJavascript };
6565

6666
if (!returnStatements.length) {
6767
return;
@@ -88,7 +88,7 @@ namespace ts.codefix {
8888
}
8989

9090
// Returns the identifiers that are never reassigned in the refactor
91-
function getConstIdentifiers(synthNamesMap: Map<SynthIdentifier>): Identifier[] {
91+
function getConstIdentifiers(synthNamesMap: ReadonlyMap<SynthIdentifier>): Identifier[] {
9292
const constIdentifiers: Identifier[] = [];
9393
synthNamesMap.forEach((val) => {
9494
if (val.numberOfAssignmentsOriginal === 0) {
@@ -249,18 +249,18 @@ namespace ts.codefix {
249249
}
250250
}
251251

252-
function getNewNameIfConflict(name: Identifier, originalNames: Map<Symbol[]>): SynthIdentifier {
253-
const numVarsSameName = (originalNames.get(name.text) || []).length;
252+
function getNewNameIfConflict(name: Identifier, originalNames: ReadonlyMap<Symbol[]>): SynthIdentifier {
253+
const numVarsSameName = (originalNames.get(name.text) || emptyArray).length;
254254
const numberOfAssignmentsOriginal = 0;
255255
const identifier = numVarsSameName === 0 ? name : createIdentifier(name.text + "_" + numVarsSameName);
256256
return { identifier, types: [], numberOfAssignmentsOriginal };
257257
}
258258

259259
// dispatch function to recursively build the refactoring
260260
// should be kept up to date with isFixablePromiseHandler in suggestionDiagnostics.ts
261-
function transformExpression(node: Expression, transformer: Transformer, outermostParent: CallExpression, prevArgName?: SynthIdentifier): Statement[] {
261+
function transformExpression(node: Expression, transformer: Transformer, outermostParent: CallExpression, prevArgName?: SynthIdentifier): ReadonlyArray<Statement> {
262262
if (!node) {
263-
return [];
263+
return emptyArray;
264264
}
265265

266266
const originalType = isIdentifier(node) && transformer.originalTypeMap.get(getNodeId(node).toString());
@@ -280,10 +280,10 @@ namespace ts.codefix {
280280
}
281281

282282
codeActionSucceeded = false;
283-
return [];
283+
return emptyArray;
284284
}
285285

286-
function transformCatch(node: CallExpression, transformer: Transformer, prevArgName?: SynthIdentifier): Statement[] {
286+
function transformCatch(node: CallExpression, transformer: Transformer, prevArgName?: SynthIdentifier): ReadonlyArray<Statement> {
287287
const func = node.arguments[0];
288288
const argName = getArgName(func, transformer);
289289
const shouldReturn = transformer.setOfExpressionsToReturn.get(getNodeId(node).toString());
@@ -336,7 +336,7 @@ namespace ts.codefix {
336336
return newSynthName;
337337
}
338338

339-
function transformThen(node: CallExpression, transformer: Transformer, outermostParent: CallExpression, prevArgName?: SynthIdentifier): Statement[] {
339+
function transformThen(node: CallExpression, transformer: Transformer, outermostParent: CallExpression, prevArgName?: SynthIdentifier): ReadonlyArray<Statement> {
340340
const [res, rej] = node.arguments;
341341

342342
if (!res) {
@@ -356,18 +356,18 @@ namespace ts.codefix {
356356
const catchArg = argNameRej ? argNameRej.identifier.text : "e";
357357
const catchClause = createCatchClause(catchArg, createBlock(transformationBody2));
358358

359-
return [createTry(tryBlock, catchClause, /* finallyBlock */ undefined) as Statement];
359+
return [createTry(tryBlock, catchClause, /* finallyBlock */ undefined)];
360360
}
361361

362362
return transformExpression(node.expression, transformer, node, argNameRes).concat(transformationBody);
363363
}
364364

365-
function getFlagOfIdentifier(node: Identifier, constIdentifiers: Identifier[]): NodeFlags {
365+
function getFlagOfIdentifier(node: Identifier, constIdentifiers: ReadonlyArray<Identifier>): NodeFlags {
366366
const inArr: boolean = constIdentifiers.some(elem => elem.text === node.text);
367367
return inArr ? NodeFlags.Const : NodeFlags.Let;
368368
}
369369

370-
function transformPromiseCall(node: Expression, transformer: Transformer, prevArgName?: SynthIdentifier): Statement[] {
370+
function transformPromiseCall(node: Expression, transformer: Transformer, prevArgName?: SynthIdentifier): ReadonlyArray<Statement> {
371371
const shouldReturn = transformer.setOfExpressionsToReturn.get(getNodeId(node).toString());
372372
// the identifier is empty when the handler (.then()) ignores the argument - In this situation we do not need to save the result of the promise returning call
373373
const originalNodeParent = node.original ? node.original.parent : node.parent;
@@ -381,23 +381,23 @@ namespace ts.codefix {
381381
return [createReturn(getSynthesizedDeepClone(node))];
382382
}
383383

384-
function createTransformedStatement(prevArgName: SynthIdentifier | undefined, rightHandSide: Expression, transformer: Transformer): MutableNodeArray<Statement> {
384+
function createTransformedStatement(prevArgName: SynthIdentifier | undefined, rightHandSide: Expression, transformer: Transformer): ReadonlyArray<Statement> {
385385
if (!prevArgName || prevArgName.identifier.text.length === 0) {
386386
// if there's no argName to assign to, there still might be side effects
387-
return createNodeArray([createStatement(rightHandSide)]);
387+
return [createStatement(rightHandSide)];
388388
}
389389

390390
if (prevArgName.types.length < prevArgName.numberOfAssignmentsOriginal) {
391391
// if the variable has already been declared, we don't need "let" or "const"
392-
return createNodeArray([createStatement(createAssignment(getSynthesizedDeepClone(prevArgName.identifier), rightHandSide))]);
392+
return [createStatement(createAssignment(getSynthesizedDeepClone(prevArgName.identifier), rightHandSide))];
393393
}
394394

395-
return createNodeArray([createVariableStatement(/*modifiers*/ undefined,
396-
(createVariableDeclarationList([createVariableDeclaration(getSynthesizedDeepClone(prevArgName.identifier), /*type*/ undefined, rightHandSide)], getFlagOfIdentifier(prevArgName.identifier, transformer.constIdentifiers))))]);
395+
return [createVariableStatement(/*modifiers*/ undefined,
396+
(createVariableDeclarationList([createVariableDeclaration(getSynthesizedDeepClone(prevArgName.identifier), /*type*/ undefined, rightHandSide)], getFlagOfIdentifier(prevArgName.identifier, transformer.constIdentifiers))))];
397397
}
398398

399399
// should be kept up to date with isFixablePromiseArgument in suggestionDiagnostics.ts
400-
function getTransformationBody(func: Expression, prevArgName: SynthIdentifier | undefined, argName: SynthIdentifier | undefined, parent: CallExpression, transformer: Transformer): NodeArray<Statement> {
400+
function getTransformationBody(func: Expression, prevArgName: SynthIdentifier | undefined, argName: SynthIdentifier | undefined, parent: CallExpression, transformer: Transformer): ReadonlyArray<Statement> {
401401

402402
const shouldReturn = transformer.setOfExpressionsToReturn.get(getNodeId(parent).toString());
403403
switch (func.kind) {
@@ -410,9 +410,9 @@ namespace ts.codefix {
410410
break;
411411
}
412412

413-
const synthCall = createCall(getSynthesizedDeepClone(func) as Identifier, /*typeArguments*/ undefined, argName ? [argName.identifier] : []);
413+
const synthCall = createCall(getSynthesizedDeepClone(func as Identifier), /*typeArguments*/ undefined, argName ? [argName.identifier] : emptyArray);
414414
if (shouldReturn) {
415-
return createNodeArray([createReturn(synthCall)]);
415+
return [createReturn(synthCall)];
416416
}
417417

418418
const type = transformer.originalTypeMap.get(getNodeId(func).toString()) || transformer.checker.getTypeAtLocation(func);
@@ -450,15 +450,15 @@ namespace ts.codefix {
450450
}
451451
}
452452

453-
return shouldReturn ? getSynthesizedDeepClones(createNodeArray(refactoredStmts)) :
454-
removeReturns(createNodeArray(refactoredStmts), prevArgName!.identifier, transformer, seenReturnStatement);
453+
return shouldReturn ? refactoredStmts.map(s => getSynthesizedDeepClone(s)) :
454+
removeReturns(refactoredStmts, prevArgName!.identifier, transformer, seenReturnStatement);
455455
}
456456
else {
457457
const innerRetStmts = getReturnStatementsWithPromiseHandlers(createReturn(funcBody));
458458
const innerCbBody = getInnerTransformationBody(transformer, innerRetStmts, prevArgName);
459459

460460
if (innerCbBody.length > 0) {
461-
return createNodeArray(innerCbBody);
461+
return innerCbBody;
462462
}
463463

464464
if (!shouldReturn) {
@@ -473,7 +473,7 @@ namespace ts.codefix {
473473
return transformedStatement;
474474
}
475475
else {
476-
return createNodeArray([createReturn(getSynthesizedDeepClone(funcBody))]);
476+
return [createReturn(getSynthesizedDeepClone(funcBody))];
477477
}
478478
}
479479
}
@@ -482,7 +482,7 @@ namespace ts.codefix {
482482
codeActionSucceeded = false;
483483
break;
484484
}
485-
return createNodeArray([]);
485+
return emptyArray;
486486
}
487487

488488
function getLastCallSignature(type: Type, checker: TypeChecker): Signature | undefined {
@@ -491,7 +491,7 @@ namespace ts.codefix {
491491
}
492492

493493

494-
function removeReturns(stmts: NodeArray<Statement>, prevArgName: Identifier, transformer: Transformer, seenReturnStatement: boolean): NodeArray<Statement> {
494+
function removeReturns(stmts: ReadonlyArray<Statement>, prevArgName: Identifier, transformer: Transformer, seenReturnStatement: boolean): ReadonlyArray<Statement> {
495495
const ret: Statement[] = [];
496496
for (const stmt of stmts) {
497497
if (isReturnStatement(stmt)) {
@@ -512,15 +512,15 @@ namespace ts.codefix {
512512
(createVariableDeclarationList([createVariableDeclaration(prevArgName, /*type*/ undefined, createIdentifier("undefined"))], getFlagOfIdentifier(prevArgName, transformer.constIdentifiers)))));
513513
}
514514

515-
return createNodeArray(ret);
515+
return ret;
516516
}
517517

518518

519-
function getInnerTransformationBody(transformer: Transformer, innerRetStmts: Node[], prevArgName?: SynthIdentifier) {
519+
function getInnerTransformationBody(transformer: Transformer, innerRetStmts: ReadonlyArray<Node>, prevArgName?: SynthIdentifier) {
520520

521521
let innerCbBody: Statement[] = [];
522522
for (const stmt of innerRetStmts) {
523-
forEachChild(stmt, function visit(node: Node) {
523+
forEachChild(stmt, function visit(node) {
524524
if (isCallExpression(node)) {
525525
const temp = transformExpression(node, transformer, node, prevArgName);
526526
innerCbBody = innerCbBody.concat(temp);

0 commit comments

Comments
 (0)