Skip to content

Commit 8834e87

Browse files
author
Andy Hanson
committed
ChangeTracker: Combine deleteDeclaration, deleteNode, and deleteNodeInList
1 parent d957b1c commit 8834e87

15 files changed

+125
-154
lines changed

src/services/codefixes/convertFunctionToEs6Class.ts

+4-20
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ namespace ts.codefix {
1313
});
1414

1515
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker): void {
16-
const deletedNodes: { node: Node, inList: boolean }[] = [];
1716
const ctorSymbol = checker.getSymbolAtLocation(getTokenAtPosition(sourceFile, position))!;
1817

1918
if (!ctorSymbol || !(ctorSymbol.flags & (SymbolFlags.Function | SymbolFlags.Variable))) {
@@ -28,7 +27,7 @@ namespace ts.codefix {
2827
switch (ctorDeclaration.kind) {
2928
case SyntaxKind.FunctionDeclaration:
3029
precedingNode = ctorDeclaration;
31-
deleteNode(ctorDeclaration);
30+
changes.delete(sourceFile, ctorDeclaration);
3231
newClassDeclaration = createClassFromFunctionDeclaration(ctorDeclaration as FunctionDeclaration);
3332
break;
3433

@@ -37,10 +36,10 @@ namespace ts.codefix {
3736
newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration as VariableDeclaration);
3837
if ((<VariableDeclarationList>ctorDeclaration.parent).declarations.length === 1) {
3938
copyComments(precedingNode, newClassDeclaration!, sourceFile); // TODO: GH#18217
40-
deleteNode(precedingNode);
39+
changes.delete(sourceFile, precedingNode);
4140
}
4241
else {
43-
deleteNode(ctorDeclaration, /*inList*/ true);
42+
changes.delete(sourceFile, ctorDeclaration);
4443
}
4544
break;
4645
}
@@ -53,21 +52,6 @@ namespace ts.codefix {
5352

5453
// Because the preceding node could be touched, we need to insert nodes before delete nodes.
5554
changes.insertNodeAfter(sourceFile, precedingNode!, newClassDeclaration);
56-
for (const { node, inList } of deletedNodes) {
57-
if (inList) {
58-
changes.deleteNodeInList(sourceFile, node);
59-
}
60-
else {
61-
changes.deleteNode(sourceFile, node);
62-
}
63-
}
64-
65-
function deleteNode(node: Node, inList = false) {
66-
// If parent node has already been deleted, do nothing
67-
if (!deletedNodes.some(n => isNodeDescendantOf(node, n.node))) {
68-
deletedNodes.push({ node, inList });
69-
}
70-
}
7155

7256
function createClassElementsFromSymbol(symbol: Symbol) {
7357
const memberElements: ClassElement[] = [];
@@ -115,7 +99,7 @@ namespace ts.codefix {
11599
// delete the entire statement if this expression is the sole expression to take care of the semicolon at the end
116100
const nodeToDelete = assignmentBinaryExpression.parent && assignmentBinaryExpression.parent.kind === SyntaxKind.ExpressionStatement
117101
? assignmentBinaryExpression.parent : assignmentBinaryExpression;
118-
deleteNode(nodeToDelete);
102+
changes.delete(sourceFile, nodeToDelete);
119103

120104
if (!assignmentBinaryExpression.right) {
121105
return createProperty([], modifiers, symbol.name, /*questionToken*/ undefined,

src/services/codefixes/convertToEs6Module.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ namespace ts.codefix {
197197
if (isExportsOrModuleExportsOrAlias(sourceFile, left)) {
198198
if (isExportsOrModuleExportsOrAlias(sourceFile, right)) {
199199
// `const alias = module.exports;` or `module.exports = alias;` can be removed.
200-
changes.deleteNode(sourceFile, assignment.parent);
200+
changes.delete(sourceFile, assignment.parent);
201201
}
202202
else {
203203
const replacement = isObjectLiteralExpression(right) ? tryChangeModuleExportsObject(right)
@@ -297,7 +297,7 @@ namespace ts.codefix {
297297
if (!right.name) changes.insertName(sourceFile, right, name);
298298

299299
const semi = findChildOfKind(parent, SyntaxKind.SemicolonToken, sourceFile);
300-
if (semi) changes.deleteNode(sourceFile, semi, { useNonAdjustedEndPosition: true });
300+
if (semi) changes.delete(sourceFile, semi);
301301
}
302302
else {
303303
// `exports.f = function g() {}` -> `export const f = function g() {}` -- just replace `exports.` with `export const `

src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ namespace ts.codefix {
2929

3030
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, constructor: ConstructorDeclaration, superCall: ExpressionStatement): void {
3131
changes.insertNodeAtConstructorStart(sourceFile, constructor, superCall);
32-
changes.deleteNode(sourceFile, superCall);
32+
changes.delete(sourceFile, superCall);
3333
}
3434

3535
function getNodes(sourceFile: SourceFile, pos: number): { readonly constructor: ConstructorDeclaration, readonly superCall: ExpressionStatement } | undefined {

src/services/codefixes/fixUnreachableCode.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ namespace ts.codefix {
3232
// falls through
3333
case SyntaxKind.WhileStatement:
3434
case SyntaxKind.ForStatement:
35-
changes.deleteNode(sourceFile, container);
35+
changes.delete(sourceFile, container);
3636
break;
3737
default:
3838
if (isBlock(statement.parent)) {
3939
split(sliceAfter(statement.parent.statements, statement), shouldRemove, (start, end) => changes.deleteNodeRange(sourceFile, start, end));
4040
}
4141
else {
42-
changes.deleteNode(sourceFile, statement);
42+
changes.delete(sourceFile, statement);
4343
}
4444
}
4545
}

src/services/codefixes/fixUnusedIdentifier.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace ts.codefix {
2222

2323
const importDecl = tryGetFullImport(token);
2424
if (importDecl) {
25-
const changes = textChanges.ChangeTracker.with(context, t => t.deleteNode(sourceFile, importDecl));
25+
const changes = textChanges.ChangeTracker.with(context, t => t.delete(sourceFile, importDecl));
2626
return [createCodeFixAction(fixName, changes, [Diagnostics.Remove_import_from_0, showModuleSpecifier(importDecl)], fixIdDelete, Diagnostics.Delete_all_unused_declarations)];
2727
}
2828
const delDestructure = textChanges.ChangeTracker.with(context, t =>
@@ -67,7 +67,7 @@ namespace ts.codefix {
6767
case fixIdDelete: {
6868
const importDecl = tryGetFullImport(token);
6969
if (importDecl) {
70-
changes.deleteDeclaration(sourceFile, importDecl);
70+
changes.delete(sourceFile, importDecl);
7171
}
7272
else if (!tryDeleteFullDestructure(token, changes, sourceFile, checker, sourceFiles, /*isFixAll*/ true) &&
7373
!tryDeleteFullVariableStatement(sourceFile, token, changes)) {
@@ -94,15 +94,15 @@ namespace ts.codefix {
9494
tryDeleteParameter(changes, sourceFile, decl, checker, sourceFiles, isFixAll);
9595
}
9696
else {
97-
changes.deleteDeclaration(sourceFile, decl);
97+
changes.delete(sourceFile, decl);
9898
}
9999
return true;
100100
}
101101

102102
function tryDeleteFullVariableStatement(sourceFile: SourceFile, token: Node, changes: textChanges.ChangeTracker): boolean {
103103
const declarationList = tryCast(token.parent, isVariableDeclarationList);
104104
if (declarationList && declarationList.getChildren(sourceFile)[0] === token) {
105-
changes.deleteDeclaration(sourceFile, declarationList.parent.kind === SyntaxKind.VariableStatement ? declarationList.parent : declarationList);
105+
changes.delete(sourceFile, declarationList.parent.kind === SyntaxKind.VariableStatement ? declarationList.parent : declarationList);
106106
return true;
107107
}
108108
return false;
@@ -140,7 +140,7 @@ namespace ts.codefix {
140140
FindAllReferences.Core.eachSymbolReferenceInFile(token, checker, sourceFile, (ref: Node) => {
141141
if (ref.parent.kind === SyntaxKind.PropertyAccessExpression) ref = ref.parent;
142142
if (ref.parent.kind === SyntaxKind.BinaryExpression && ref.parent.parent.kind === SyntaxKind.ExpressionStatement) {
143-
changes.deleteDeclaration(sourceFile, ref.parent.parent);
143+
changes.delete(sourceFile, ref.parent.parent);
144144
}
145145
});
146146
}
@@ -151,13 +151,13 @@ namespace ts.codefix {
151151
tryDeleteParameter(changes, sourceFile, parent, checker, sourceFiles, isFixAll);
152152
}
153153
else {
154-
changes.deleteDeclaration(sourceFile, isImportClause(parent) ? token : isComputedPropertyName(parent) ? parent.parent : parent);
154+
changes.delete(sourceFile, isImportClause(parent) ? token : isComputedPropertyName(parent) ? parent.parent : parent);
155155
}
156156
}
157157

158158
function tryDeleteParameter(changes: textChanges.ChangeTracker, sourceFile: SourceFile, p: ParameterDeclaration, checker: TypeChecker, sourceFiles: ReadonlyArray<SourceFile>, isFixAll: boolean): void {
159159
if (mayDeleteParameter(p, checker, isFixAll)) {
160-
changes.deleteDeclaration(sourceFile, p);
160+
changes.delete(sourceFile, p);
161161
deleteUnusedArguments(changes, sourceFile, p, sourceFiles, checker);
162162
}
163163
}
@@ -199,7 +199,7 @@ namespace ts.codefix {
199199
FindAllReferences.Core.eachSignatureCall(deletedParameter.parent, sourceFiles, checker, call => {
200200
const index = deletedParameter.parent.parameters.indexOf(deletedParameter);
201201
if (call.arguments.length > index) { // Just in case the call didn't provide enough arguments.
202-
changes.deleteDeclaration(sourceFile, call.arguments[index]);
202+
changes.delete(sourceFile, call.arguments[index]);
203203
}
204204
});
205205
}

src/services/organizeImports.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,7 @@ namespace ts.OrganizeImports {
6363

6464
// Delete or replace the first import.
6565
if (newImportDecls.length === 0) {
66-
changeTracker.deleteNode(sourceFile, oldImportDecls[0], {
67-
useNonAdjustedStartPosition: true, // Leave header comment in place
68-
useNonAdjustedEndPosition: false,
69-
});
66+
changeTracker.delete(sourceFile, oldImportDecls[0]);
7067
}
7168
else {
7269
// Note: Delete the surrounding trivia because it will have been retained in newImportDecls.
@@ -79,7 +76,7 @@ namespace ts.OrganizeImports {
7976

8077
// Delete any subsequent imports.
8178
for (let i = 1; i < oldImportDecls.length; i++) {
82-
changeTracker.deleteNode(sourceFile, oldImportDecls[i]);
79+
changeTracker.delete(sourceFile, oldImportDecls[i]);
8380
}
8481
}
8582
}

src/services/refactors/convertExport.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ namespace ts.refactor {
7878

7979
function changeExport(exportingSourceFile: SourceFile, { wasDefault, exportNode, exportName }: Info, changes: textChanges.ChangeTracker, checker: TypeChecker): void {
8080
if (wasDefault) {
81-
changes.deleteNode(exportingSourceFile, Debug.assertDefined(findModifier(exportNode, SyntaxKind.DefaultKeyword)));
81+
changes.delete(exportingSourceFile, Debug.assertDefined(findModifier(exportNode, SyntaxKind.DefaultKeyword)));
8282
}
8383
else {
8484
const exportKeyword = Debug.assertDefined(findModifier(exportNode, SyntaxKind.ExportKeyword));
@@ -155,7 +155,7 @@ namespace ts.refactor {
155155
}
156156
else {
157157
// `import foo, { bar } from "./a"` --> `import { bar, foo } from "./a";`
158-
changes.deleteNode(importingSourceFile, ref);
158+
changes.delete(importingSourceFile, ref);
159159
changes.insertNodeAtEndOfList(importingSourceFile, namedBindings.elements, spec);
160160
}
161161
break;
@@ -183,7 +183,7 @@ namespace ts.refactor {
183183
changes.replaceNode(importingSourceFile, spec.parent, defaultImport);
184184
}
185185
else {
186-
changes.deleteNodeInList(importingSourceFile, spec);
186+
changes.delete(importingSourceFile, spec);
187187
changes.insertNodeBefore(importingSourceFile, spec.parent, defaultImport);
188188
}
189189
}

src/services/refactors/extractSymbol.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,7 @@ namespace ts.refactor.extractSymbol {
10901090
// Consume
10911091
if (node.parent.kind === SyntaxKind.ExpressionStatement) {
10921092
// If the parent is an expression statement, delete it.
1093-
changeTracker.deleteNode(context.file, node.parent, textChanges.useNonAdjustedPositions);
1093+
changeTracker.delete(context.file, node.parent);
10941094
}
10951095
else {
10961096
const localReference = createIdentifier(localNameText);

src/services/refactors/moveToNewFile.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ namespace ts.refactor {
325325
break;
326326
case SyntaxKind.ImportEqualsDeclaration:
327327
if (isUnused(importDecl.name)) {
328-
changes.deleteNode(sourceFile, importDecl);
328+
changes.delete(sourceFile, importDecl);
329329
}
330330
break;
331331
case SyntaxKind.VariableDeclaration:
@@ -342,19 +342,19 @@ namespace ts.refactor {
342342
const namedBindingsUnused = !namedBindings ||
343343
(namedBindings.kind === SyntaxKind.NamespaceImport ? isUnused(namedBindings.name) : namedBindings.elements.every(e => isUnused(e.name)));
344344
if (defaultUnused && namedBindingsUnused) {
345-
changes.deleteNode(sourceFile, importDecl);
345+
changes.delete(sourceFile, importDecl);
346346
}
347347
else {
348348
if (name && defaultUnused) {
349-
changes.deleteNode(sourceFile, name);
349+
changes.delete(sourceFile, name);
350350
}
351351
if (namedBindings) {
352352
if (namedBindingsUnused) {
353-
changes.deleteNode(sourceFile, namedBindings);
353+
changes.delete(sourceFile, namedBindings);
354354
}
355355
else if (namedBindings.kind === SyntaxKind.NamedImports) {
356356
for (const element of namedBindings.elements) {
357-
if (isUnused(element.name)) changes.deleteNodeInList(sourceFile, element);
357+
if (isUnused(element.name)) changes.delete(sourceFile, element);
358358
}
359359
}
360360
}
@@ -365,20 +365,20 @@ namespace ts.refactor {
365365
switch (name.kind) {
366366
case SyntaxKind.Identifier:
367367
if (isUnused(name)) {
368-
changes.deleteNode(sourceFile, name);
368+
changes.delete(sourceFile, name);
369369
}
370370
break;
371371
case SyntaxKind.ArrayBindingPattern:
372372
break;
373373
case SyntaxKind.ObjectBindingPattern:
374374
if (name.elements.every(e => isIdentifier(e.name) && isUnused(e.name))) {
375-
changes.deleteNode(sourceFile,
375+
changes.delete(sourceFile,
376376
isVariableDeclarationList(varDecl.parent) && varDecl.parent.declarations.length === 1 ? varDecl.parent.parent : varDecl);
377377
}
378378
else {
379379
for (const element of name.elements) {
380380
if (isIdentifier(element.name) && isUnused(element.name)) {
381-
changes.deleteNode(sourceFile, element.name);
381+
changes.delete(sourceFile, element.name);
382382
}
383383
}
384384
}

0 commit comments

Comments
 (0)