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
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions