estree-toolkit icon indicating copy to clipboard operation
estree-toolkit copied to clipboard

Can I prevent CallExpression.arguments being traversed?

Open retorquere opened this issue 9 months ago • 4 comments

In a visitor, I can do something like

CallExpression(path) {
  path.get('callee').skip();
}

but since arguments isn't a node,

path.get('arguments').skip()

doesn't return something I can use this way

retorquere avatar May 10 '24 14:05 retorquere

path.get('arguments') returns an array so you would have to run .skip() on every element of the array like

path.get('arguments').forEach(p => p.skip())

sarsamurmu avatar May 10 '24 18:05 sarsamurmu

Aha, super!

Is there a way to pass a specific state into one branch? Or is state always global for the visitor?

retorquere avatar May 10 '24 20:05 retorquere

You can use NodePath.traverse function in that case

sarsamurmu avatar May 11 '24 16:05 sarsamurmu

I was stuck on a misunderstanding of how skip/travers/replaceWith interacted. I had something like this:

const { traverse, builders: b } = require('estree-toolkit');
const { parseModule } = require('meriyah');

const ast = parseModule('type(argument)')

traverse(ast, {
  CallExpression: { enter(path) {
    path.get('arguments').forEach(a => {
      a.traverse({
        Identifier: { enter(path) {
          path.replaceWith(b.literal(path.node.name))
        }},
      })

      a.skip()
    })
  }},

  Literal: { enter(path) {
    console.log('main:', path.node.value)
  }},
})

and was surprised Literal was reached even though I had called skip, but the replaceWith builds a path (I think) that wasn't marked with the skip. Calling

path.replaceWith(b.literal(path.node.name)).skip()

got me what I wanted.

retorquere avatar May 11 '24 23:05 retorquere