Skip to content

Commit 8414a96

Browse files
committed
update all reference in constructor
1 parent 88bf927 commit 8414a96

6 files changed

+42
-136
lines changed

src/services/refactors/generateGetAccessorAndSetAccessor.ts

+22-34
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
1616
declaration: AcceptedDeclaration;
1717
fieldName: AcceptedNameType;
1818
accessorName: AcceptedNameType;
19+
originalName: AcceptedNameType;
1920
}
2021

2122
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
@@ -42,7 +43,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
4243

4344
const isJS = isSourceFileJavaScript(file);
4445
const changeTracker = textChanges.ChangeTracker.fromContext(context);
45-
const { isStatic, isReadonly, fieldName, accessorName, type, container, declaration } = fieldInfo;
46+
const { isStatic, isReadonly, fieldName, accessorName, originalName, type, container, declaration } = fieldInfo;
4647

4748
suppressLeadingAndTrailingTrivia(fieldName);
4849
suppressLeadingAndTrailingTrivia(declaration);
@@ -68,7 +69,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
6869
// readonly modifier only existed in classLikeDeclaration
6970
const constructor = getFirstConstructorWithBody(<ClassLikeDeclaration>container);
7071
if (constructor) {
71-
updateReadonlyPropertyInitializerStatementConstructor(changeTracker, file, constructor, accessorName, fieldName);
72+
updateReadonlyPropertyInitializerStatementConstructor(changeTracker, context, constructor, fieldName, originalName);
7273
}
7374
}
7475
else {
@@ -123,6 +124,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
123124
isReadonly: hasReadonlyModifier(declaration),
124125
type: getTypeAnnotationNode(declaration),
125126
container: declaration.kind === SyntaxKind.Parameter ? declaration.parent.parent : declaration.parent,
127+
originalName: <AcceptedNameType>declaration.name,
126128
declaration,
127129
fieldName,
128130
accessorName,
@@ -205,37 +207,23 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
205207
: changeTracker.insertNodeAfter(file, declaration, accessor);
206208
}
207209

208-
function updateReadonlyPropertyInitializerStatementConstructor(changeTracker: textChanges.ChangeTracker, file: SourceFile, constructor: ConstructorDeclaration, accessorName: AcceptedNameType, fieldName: AcceptedNameType) {
209-
if (constructor.body) {
210-
const initializerStatement = find(constructor.body.statements, (stmt =>
211-
isExpressionStatement(stmt) &&
212-
isAssignmentExpression(stmt.expression) &&
213-
stmt.expression.operatorToken.kind === SyntaxKind.EqualsToken &&
214-
(isPropertyAccessExpression(stmt.expression.left) || isElementAccessExpression(stmt.expression.left)) &&
215-
isThis(stmt.expression.left.expression) &&
216-
(isPropertyAccessExpression(stmt.expression.left)
217-
? (getNameFromPropertyName(stmt.expression.left.name) === accessorName.text)
218-
: (isPropertyName(stmt.expression.left.argumentExpression) && isConvertableName(stmt.expression.left.argumentExpression) && getNameFromPropertyName(stmt.expression.left.argumentExpression) === accessorName.text
219-
))
220-
));
221-
if (initializerStatement) {
222-
const initializerLeftHead = (<PropertyAccessExpression | ElementAccessExpression>(<AssignmentExpression<Token<SyntaxKind.EqualsToken>>>(<ExpressionStatement>initializerStatement).expression).left);
223-
224-
if (isPropertyAccessExpression(initializerLeftHead)) {
225-
changeTracker.replaceNode(file, initializerLeftHead, updatePropertyAccess(
226-
initializerLeftHead,
227-
initializerLeftHead.expression,
228-
createIdentifier(fieldName.text)
229-
));
230-
}
231-
else {
232-
changeTracker.replaceNode(file, initializerLeftHead, updateElementAccess(
233-
initializerLeftHead,
234-
initializerLeftHead.expression,
235-
createPropertyName(fieldName.text, <AcceptedNameType>initializerLeftHead.argumentExpression)
236-
));
237-
}
238-
}
239-
}
210+
function updateReadonlyPropertyInitializerStatementConstructor(changeTracker: textChanges.ChangeTracker, context: RefactorContext, constructor: ConstructorDeclaration, fieldName: AcceptedNameType, originalName: AcceptedNameType) {
211+
if (!constructor.body) return;
212+
const { file, program, cancellationToken } = context;
213+
214+
const referenceEntries = mapDefined(FindAllReferences.getReferenceEntriesForNode(-1, originalName, program, [file], cancellationToken), entry => (
215+
(entry.type === "node" && rangeContainsRange(constructor, entry.node) && isIdentifier(entry.node) && isWriteAccess(entry.node)) ? entry.node : undefined
216+
));
217+
218+
forEach(referenceEntries, entry => {
219+
const parent = entry.parent;
220+
const accessorName = createIdentifier(fieldName.text);
221+
const node = isBinaryExpression(parent)
222+
? updateBinary(parent, accessorName, parent.right, parent.operatorToken)
223+
: isPropertyAccessExpression(parent)
224+
? updatePropertyAccess(parent, parent.expression, accessorName)
225+
: Debug.fail("Unexpected write access token");
226+
changeTracker.replaceNode(file, parent, node);
227+
});
240228
}
241229
}

tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess33.ts

+20-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,18 @@
22

33
//// class A {
44
//// public readonly /*a*/a/*b*/: number;
5+
//// public b: number;
56
//// constructor () {
6-
//// this.a = 1;
7+
//// this.a = 1; // convert
8+
//// this.a++; // convert
9+
//// ++this.a; // convert
10+
//// if (Math.random()) {
11+
//// this.a = 2; // convert
12+
//// }
13+
//// console.log(this.a); // preserve
14+
//// this.b = this.a; // preserve
715
//// }
16+
//// foo () { this.a = 2; }
817
//// }
918

1019
goTo.select("a", "b");
@@ -17,8 +26,17 @@ edit.applyRefactor({
1726
public get a(): number {
1827
return this._a;
1928
}
29+
public b: number;
2030
constructor () {
21-
this._a = 1;
31+
this._a = 1; // convert
32+
this._a++; // convert
33+
++this._a; // convert
34+
if (Math.random()) {
35+
this._a = 2; // convert
36+
}
37+
console.log(this.a); // preserve
38+
this.b = this.a; // preserve
2239
}
40+
foo () { this.a = 2; }
2341
}`,
2442
});

tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess34.ts

-24
This file was deleted.

tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess35.ts

-24
This file was deleted.

tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess36.ts

-24
This file was deleted.

tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess37.ts

-28
This file was deleted.

0 commit comments

Comments
 (0)