javascript - codemod from ForInStatement to ForStatement -
i have codemod want transform
for (var key in foo){}
into
for (var keys = 0; key < foo; key++){}
i managed far:
return j(file.source) .find(j.forinstatement) .replacewith(p => { var prop = p.node.left.declarations[0].id; var v = [j.variabledeclarator(prop, null)]; var vardec = j.variabledeclaration('var', v); var binary = j.binaryexpression('<', prop, j.identifier('foo')); var ue = j.updateexpression('++', prop, false); var block = j.blockstatement([]); var forin = j.forstatement(vardec, binary, ue, block); return forin; }) .tosource();
and that brought me far:
for (var key; key < foo; key++) {}
i'm still bit lost creating things scratch...
question:
- am doing correct? feels quite verbose, maybe way go.
- how finish? missing example
foo.length
...
ps: felix, if reading this, point me can send pull requests improve docs! happy while trying learn api. oh, , felix, nice tool guys made!
creating ast nodes directly indeed verbose. however, jscodeshift exports helper "methods" allow generate ast nodes string , let interpolate existing ast nodes (tagged templates ftw!).
your above example simplified to:
return j(file.source) .find(j.forinstatement) .replacewith(p => { var prop = p.node.left.declarations[0].id; return statement`for (var ${prop} = 0; ${prop} < foo.length; ${prop}++) ${p.node.body}`; }) .tosource();
note though template methods (expression
, statement
, statements
) have limitations (you can interpolate ast nodes can put identifier).
if wanted create foo.length
manually, have create memberexpression
:
j.memberexpression( prop, j.identifier('length') );