benjamn / recast

JavaScript syntax tree transformer, nondestructive pretty-printer, and automatic source map generator

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using newVisitor in traverse

retorquere opened this issue · comments

Since traverse accepts a newVisitor argument, I figured I could have part of the AST walked by specialized visitors, like:

const formula = 'Title + (auth ? title : year) + Title + X | Title'

const { parse, types } = require( 'recast' )
const b = types.builders

const FallbackVisitor = {
  visitNode(path) {
    if (!this[`visit${path.node.type}`]) throw new Error(`Unexpected ${path.node.type}`)
    return false
  },
}

const FormulaVisitor = {
  ...FallbackVisitor,

  visitBinaryExpression(path) {
    // expect only + here
    if (path.node.operator !== '+') throw new Error(`Unexpected operator ${path.value.operator}`)
    this.traverse(path)
  },

  visitIdentifier(path) {
    this.traverse(path)
  },

  visitConditionalExpression(path) {
    this.traverse(path)
  },
}

const RootVisitor = {
  ...FallbackVisitor,

  visitBinaryExpression(path) {
    if (path.node.operator !== '|') throw new Error(`Unexpected operator ${path.node.operator}`)
    this.traverse(path, FormulaVisitor)
  },

  visitExpressionStatement(path) {
    this.traverse(path, FormulaVisitor)
  },

  visitFile(path) {
    this.traverse(path)
  },

  visitProgram(path) {
    this.traverse(path)
  },
}

const ast = parse(formula)
types.visit(ast, RootVisitor)

but this code fails at the "expect only plus here" comment; for some reason, the root binary expression is passed to the FormulaVisitor. What am I doing wrong here?