TIP: Visit Children
有一个实用函数 ts.forEachChild
允许您访问 AST
中任何节点的所有子节点。
这是源代码的简化片段,以演示其功能:
export function forEachChild<T>(node: Node, cbNode: (node: Node) => T, cbNodeArray?: (nodes: Node[]) => T): T {
if (!node) {
return;
}
switch (node.kind) {
case SyntaxKind.BinaryExpression:
return visitNode(cbNode, (<BinaryExpression>node).left) ||
visitNode(cbNode, (<BinaryExpression>node).operatorToken) ||
visitNode(cbNode, (<BinaryExpression>node).right);
case SyntaxKind.IfStatement:
return visitNode(cbNode, (<IfStatement>node).expression) ||
visitNode(cbNode, (<IfStatement>node).thenStatement) ||
visitNode(cbNode, (<IfStatement>node).elseStatement);
// .... lots more
基本上,它会检查 node.kind
并基于此假设由 提供的接口 node
并调用 cbNode
子级的 。
但是请注意,此函数不会调用所有 visitNode
子项(例如 SyntaxKind.SemicolonToken
)。如果你想要 AST
中一个节点的所有子节点,只需调用 .getChildrenNode
例如,这是一个打印AST节点详细信息的函数:
function printAllChildren(node: ts.Node, depth = 0) {
console.log(
new Array(depth + 1).join("----"),
ts.syntaxKindToName(node.kind),
node.pos,
node.end
);
depth++;
node.getChildren().forEach((c) => printAllChildren(c, depth));
}
当我们进一步讨论解析器时,我们将看到这个函数的示例用法。