Skip to content

Refactor our AST traversal C++ API to make it more like @babel/traverse #27

@phisiart

Description

@phisiart

If we rewrite the examples from https://babel.dev/docs/babel-traverse into TypeScript:

import * as parser from "@babel/parser";
import {traverse, NodePath} from "@babel/traverse";
import * as t from "@babel/types";

const code = `function square(n) {
  return n * n;
}`;

const ast = parser.parse(code);

traverse(ast, {
  enter(path: NodePath) {
    if (path.isIdentifier({ name: "n" })) {
      // path: NodePath<t.Identifier>
      // path.node: Identifier
      path.node.name = "x";
    }
  },
});
traverse(ast, {
  FunctionDeclaration: function(path: NodePath<t.FunctionDeclaration>) {
    path.node.id.name = "x";
  },
});

There is a critical class NodePath, which has the following functionalities:

  • It stores the entire path from the root node to the current node;
  • It provides a method parent() that returns the parent NodePath;
  • It provides mutation methods:
    • path.replaceWith(newNode)
    • path.remove()
    • path.insertBefore(nodes) and path.insertAfter(nodes)
    • path.replaceWithMultiple(nodes)
  • It's covariant: a NodePath<Identifier> is a NodePath<Expression>.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions