-
Notifications
You must be signed in to change notification settings - Fork 189
/
StraightReplacementNodeHandler.ts
50 lines (41 loc) · 2.16 KB
/
StraightReplacementNodeHandler.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { errors, getSyntaxKindName, ts } from "@ts-morph/common";
import { Node } from "../../compiler";
import { CompilerFactory } from "../../factories";
import { NodeHandler } from "./NodeHandler";
import { NodeHandlerHelper } from "./NodeHandlerHelper";
/**
* Replacement handler for replacing parts of the tree that should be equal.
*/
export class StraightReplacementNodeHandler implements NodeHandler {
protected readonly helper: NodeHandlerHelper;
constructor(protected readonly compilerFactory: CompilerFactory) {
this.helper = new NodeHandlerHelper(compilerFactory);
}
handleNode(currentNode: Node, newNode: ts.Node, newSourceFile: ts.SourceFile) {
/* istanbul ignore if */
if (currentNode.getKind() !== newNode.kind) {
// support a private identifier and identifier being swapped
const kinds = [currentNode.getKind(), newNode.kind];
if (kinds.includes(ts.SyntaxKind.Identifier) && kinds.includes(ts.SyntaxKind.PrivateIdentifier)) {
currentNode.forget();
return;
}
throw new errors.InvalidOperationError(`Error replacing tree! Perhaps a syntax error was inserted `
+ `(Current: ${currentNode.getKindName()} -- New: ${getSyntaxKindName(newNode.kind)}).`);
}
if (currentNode._hasWrappedChildren())
this.handleChildren(currentNode, newNode, newSourceFile);
this.compilerFactory.replaceCompilerNode(currentNode, newNode);
}
private handleChildren(currentNode: Node, newNode: ts.Node, newSourceFile: ts.SourceFile) {
const [currentChildren, newChildren] = this.helper.getChildrenFast(currentNode, newNode, newSourceFile);
if (currentChildren.length !== newChildren.length) {
throw new Error(
`Error replacing tree: The children of the old and new trees were expected to have the `
+ `same count (${currentChildren.length}:${newChildren.length}).`,
);
}
for (let i = 0; i < currentChildren.length; i++)
this.helper.handleForValues(this, currentChildren[i], newChildren[i], newSourceFile);
}
}