Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {analyzeControlFlow, ControlFlowAnalysisNode} from '../../../flow_analysi
import {ProgramInfo, projectFile, Replacement, TextUpdate} from '../../../../../../utils/tsurge';
import {traverseAccess} from '../../../utils/traverse_access';
import {UniqueNamesGenerator} from '../../../utils/unique_names';
import {createNewBlockToInsertVariable} from '../helpers/create_block_arrow_function';
import {createNewBlockToInsertVariable} from './create_block_arrow_function';
import assert from 'assert';

export interface NarrowableTsReferences {
Expand Down Expand Up @@ -123,6 +123,23 @@ export function migrateStandardTsReference(
replacements.push(
...createNewBlockToInsertVariable(parent, filePath, temporaryVariableStr),
);
} else if (shouldInsertAtMethodStart(reference, recommendedNode, referenceNodeInBlock)) {
const blockNode = recommendedNode as ts.Block;
const firstStatement = blockNode.statements[0];
const leadingSpace = firstStatement
? ts.getLineAndCharacterOfPosition(sf, firstStatement.getStart())
: ts.getLineAndCharacterOfPosition(sf, referenceNodeInBlock.getStart());

replacements.push(
new Replacement(
filePath,
new TextUpdate({
position: firstStatement.getStart(),
end: firstStatement.getStart(),
toInsert: `${temporaryVariableStr}\n${' '.repeat(leadingSpace.character)}`,
}),
),
);
} else {
const leadingSpace = ts.getLineAndCharacterOfPosition(sf, referenceNodeInBlock.getStart());

Expand Down Expand Up @@ -151,3 +168,43 @@ export function migrateStandardTsReference(
}
}
}

/**
* Determines if a temporary variable should be inserted at the start of a method.
*
* This function performs several checks to ensure it's safe to insert a temporary variable:
* 1. Verifies the recommended node is a method declaration block
* 2. Ensures all references are contained within the method body
* 3. Confirms the reference node is the first statement in the method
* 4. Validates the reference node is an expression statement with an assignment operation
*/
function shouldInsertAtMethodStart(
Comment thread
aparzi marked this conversation as resolved.
references: NarrowableTsReferences,
recommendedNode: ts.Node,
referenceNodeInBlock: ts.Node,
): boolean {
if (!ts.isBlock(recommendedNode) || !ts.isMethodDeclaration(recommendedNode.parent)) {
return false;
}

const methodBody = recommendedNode;
const allReferencesInMethod = references.accesses.every((access) => {
let current: ts.Node | undefined = access;
while (current && current !== methodBody) {
current = current.parent;
}
return current === methodBody;
});

if (!allReferencesInMethod) {
return false;
}

return (
methodBody.statements.length > 0 &&
ts.isExpressionStatement(referenceNodeInBlock) &&
methodBody.statements[0] === referenceNodeInBlock &&
ts.isBinaryExpression(referenceNodeInBlock.expression) &&
referenceNodeInBlock.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// tslint:disable

import {Input} from '@angular/core';

export class TestMigrationComponent {
@Input() public model: any;

public onSaveClick(): void {
this.model.requisitionId = 145;
this.model.comment = 'value';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,21 @@ class ModifierScenarios {
@CustomDecorator()
protected readonly usingCustomDecorator = input(true);
}
@@@@@@ multiple_references_in_method.ts @@@@@@

// tslint:disable

import {input} from '@angular/core';

export class TestMigrationComponent {
public readonly model = input<any>();

public onSaveClick(): void {
const model = this.model();
model.requisitionId = 145;
model.comment = 'value';
}
}
@@@@@@ mutate.ts @@@@@@

// tslint:disable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,21 @@ class ModifierScenarios {
@CustomDecorator()
protected readonly usingCustomDecorator = input(true);
}
@@@@@@ multiple_references_in_method.ts @@@@@@

// tslint:disable

import {input} from '@angular/core';

export class TestMigrationComponent {
public readonly model = input<any>();

public onSaveClick(): void {
const model = this.model();
model.requisitionId = 145;
model.comment = 'value';
}
}
@@@@@@ mutate.ts @@@@@@

// tslint:disable
Expand Down