Find node of specific SyntaxKind in ASL tree with typescript compiler api

123 Views Asked by At

How can one find nodes of a specific kind in an ASL tree with typescript compiler api ?

I've tried using forEachChild to get the nodes and then iterate over those to filter the elements I want. However forEachChild doesn't seem to walk the tree ?

What I hope to find

findNodes(node, isReturnStatement);
findNodes(node, isClassDeclaration);
findNodes(node, is...);

What I have tried:

    const children: Node[] = [];
    node.forEachChild((childNode) => {
      children.push(childNode);
    });
    return node.filter(isReturnStatement);

1

There are 1 best solutions below

0
Ezzabuzaid On

To find a node of the specific kind you've to traverse the Abstract Syntax Tree (AST) and do some if conditions to find the kind of node you're interested in.

I'll assume you're doing some sort of transformation so I'll use transform API to traverse the AST.

The following code updates the function name and removes the return statement

import * as ts from 'typescript';

const code = `function myFn() {
   return 'returnValue'
}`;

const sourceFile = ts.createSourceFile(
  'index.ts',
  code,
  ts.ScriptTarget.Latest
);

const result = ts.transform<ts.SourceFile>(sourceFile, [
    (context) => {
        const visit: ts.Visitor = (node) => {
            if (ts.isFunctionDeclaration(node)) {
                const updatedNode = ts.factory.updateFunctionDeclaration(
                    node,
                    node.modifiers,
                    node.asteriskToken,
                    ts.factory.createIdentifier('newFnName'),
                    node.typeParameters,
                    node.parameters,
                    node.type,
                    node.body
                );
                return ts.visitEachChild(updatedNode, visit, context);
            }
            if (ts.isReturnStatement(node)) {
                return ts.factory.updateReturnStatement(node, undefined);
            }
            return ts.visitEachChild(node, visit, context);
        };
        return (node) => ts.visitEachChild(node, visit, context);
    },
]);