sarsamurmu / estree-toolkit

Tools for working with ESTree AST
https://estree-toolkit.netlify.app/
MIT License
54 stars 1 forks source link

Validation fails with UpdateExpression on ArrowFunction body #6

Closed trueadm closed 1 year ago

trueadm commented 1 year ago

Given the below:

const x = () => foo++;

This fails and gives me some strange validation error about a circular structure to JSON. I assume the issue is assuming arrow functions must have block statements.

sarsamurmu commented 1 year ago

I'm looking into it.

sarsamurmu commented 1 year ago

I'm unable to reproduce this issue, here is my code

const { parseModule } = require('meriyah')
const astring = require('astring')

const ast = parseModule(`
  const x = () => {};
`)

traverse(ast, {
  $: { scope: true, validateNodes: true },
  ArrowFunctionExpression(path) {
    path.get('body').replaceWith(b.updateExpression('++', b.identifier('foo'), false))
  }
})

console.log(astring.generate(ast))
// Output: const x = () => foo++;

Can you share your code?

trueadm commented 1 year ago

Your arrow function has a BlockStatement. Try making it an expression instead;

const ast = parseModule(`
  let y = 0;
  const x = () => y++;
`)
sarsamurmu commented 1 year ago

It works on my system, I also ran it on Replit - https://replit.com/@SarsaMurmu/TastyGivingVendors#index.js. It works there too. I'm not sure what is causing this issue.

trueadm commented 1 year ago

Ah, I think I know what it might be. It's because my nodes have an additional parent property and it seems the validation logic must be looking at this property. Maybe the parent property can be skipped internally to help my use-case?

If I use the builders this is also evident:

const body = b.identifier('test');
body.parent = someOtherNode
b.arrowFunctionExpression(params, body)

Edit: I made the parent property non-enumerable and that seems to fix it.