Skip to content

Commit

Permalink
feat: #508 - Expose Node.forgetDescendants.
Browse files Browse the repository at this point in the history
  • Loading branch information
dsherret committed Dec 2, 2018
1 parent 53de711 commit ee87eac
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 5 deletions.
3 changes: 3 additions & 0 deletions docs/manipulation/performance.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ The main way to improve performance when manipulating, is to "forget" a node whe

```ts setup: let personInterface: InterfaceDeclaration;
personInterface.forget();

// or to only forget a node's descendants that are currently in the wrapped cache
sourceFile.forgetDescendants();
```

That will stop tracking the node and all its previously navigated descendants (ex. in this case, `nameProperty` as well).
Expand Down
14 changes: 14 additions & 0 deletions lib/ts-simple-ast.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4191,6 +4191,10 @@ export declare class Node<NodeType extends ts.Node = ts.Node> {
* This is useful if you want to improve the performance of manipulation by not tracking this node anymore.
*/
forget(): void;
/**
* Forgets the descendants of this node.
*/
forgetDescendants(): this;
/**
* Gets if the compiler node was forgotten.
*
Expand Down Expand Up @@ -8188,11 +8192,21 @@ export interface StatementedNode {
* Gets the direct variable statement children.
*/
getVariableStatements(): VariableStatement[];
/**
* Gets a variable statement.
* @param name - Name of one of the variable statement's declarations.
*/
getVariableStatement(name: string): VariableStatement | undefined;
/**
* Gets a variable statement.
* @param findFunction - Function to use to find the variable statement.
*/
getVariableStatement(findFunction: (declaration: VariableStatement) => boolean): VariableStatement | undefined;
/**
* Gets a variable statement or throws if it doesn't exist.
* @param name - Name of one of the variable statement's declarations.
*/
getVariableStatementOrThrow(name: string): VariableStatement;
/**
* Gets a variable statement or throws if it doesn't exist.
* @param findFunction - Function to use to find the variable statement.
Expand Down
9 changes: 5 additions & 4 deletions src/compiler/ast/common/Node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,17 +106,18 @@ export class Node<NodeType extends ts.Node = ts.Node> {
if (this.wasForgotten())
return;

this._forgetChildren();
this.forgetDescendants();
this._forgetOnlyThis();
}

/**
* Forgets the children of this node.
* @internal
* Forgets the descendants of this node.
*/
_forgetChildren() {
forgetDescendants() {
for (const child of this._getChildrenInCacheIterator())
child.forget();

return this;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/ast/module/SourceFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ export class SourceFile extends SourceFileBase<ts.SourceFile> {
* @param textChanges - Text changes.
*/
applyTextChanges(textChanges: ReadonlyArray<TextChange>) {
this._forgetChildren();
this.forgetDescendants();
replaceNodeText({
sourceFile: this._sourceFile,
start: 0,
Expand Down
11 changes: 11 additions & 0 deletions src/tests/compiler/common/nodeTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1542,6 +1542,17 @@ class MyClass {
});
});

describe(nameof<Node>(n => n.forgetDescendants), () => {
it("should only forget the descendants", () => {
const { firstChild } = getInfoFromText<EnumDeclaration>("enum MyEnum { member }");
const member = firstChild.getMembers()[0];
firstChild.forgetDescendants();
expect(member.wasForgotten()).to.be.true;
expect(firstChild.wasForgotten()).to.be.false;
expect(() => member.compilerNode).to.throw(errors.InvalidOperationError, getExpectedForgottenMessage("member"));
});
});

describe(nameof<Node>(n => n.getNonWhitespaceStart), () => {
function doTest(text: string, selectNode: (sourceFile: SourceFile) => Node, expected: number) {
const { sourceFile } = getInfoFromText(text);
Expand Down

0 comments on commit ee87eac

Please sign in to comment.