estraverse icon indicating copy to clipboard operation
estraverse copied to clipboard

replace(): replace with 2 nodes?

Open rstacruz opened this issue 10 years ago • 10 comments

Would it be possible to replace a node with multiple statements? I understand this can't work on all places (only in bodys), but it'd be useful for some cases.

estraverse.replace(tree, {
  enter: function (node, parent) {
    if (/* something */) {
      return [
        { type: 'FunctionDeclaration', body: /* ... */ },
        { type: 'FunctionDeclaration', body: /* ... */ } ];
    }
  }
});

An example use case would be to to change a ForStatement (for (x;y;z){a}) into a WhileStatement (x; while (y) { z; a; }), which will be useful for js2coffee.

rstacruz avatar Jan 23 '15 04:01 rstacruz

Came here to ask the same question. If it is possible it's undocumented.

goatslacker avatar Feb 09 '15 10:02 goatslacker

Ah, currently, estraverse doesn't support it.

Constellation avatar Feb 09 '15 11:02 Constellation

I second this feature.

exander77 avatar May 20 '16 14:05 exander77

Just came looking for this too. A workaround is to run logic on the parent, replace the target child with the two children on the parent, then return the parent when you've traversed to that parent.

trusktr avatar Jan 22 '17 05:01 trusktr

Temporary fix:

return {
    type: esprima.Syntax.Program,
    body: bodyStatementsArray,
}

Will do pull request later

WelaurS avatar May 26 '19 09:05 WelaurS

+1

sanex3339 avatar Dec 29 '19 20:12 sanex3339

+1

lwyj123 avatar Mar 20 '20 05:03 lwyj123

+1

rootgrandfather avatar Dec 28 '20 07:12 rootgrandfather

Dirty workaround that should work with BlockStatement:

estraverse.replace(tree, {
  enter: (node, parent) => {
    const nodes = // ...
    const index = parent.body.findIndex(n => n === node)
    parent.body.splice(index, 1, ...nodes)
  }
})

Using this instead of WelaurS' fix, because inserting a Program node inside a BlockStatement can mess up escodegen's formatting.

ptrcnull avatar Feb 24 '21 17:02 ptrcnull

Can we make ptrcnull's implementation into codebase ?

wlbksy avatar May 10 '21 04:05 wlbksy