我有一个要转换的codemod

for (var key in foo){}


进入

for (var keys = 0; key < foo; key++){}


我设法做到了这一点:

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();


that brought me this far

for (var key; key < foo; key++)
  {}


我仍然迷失了从头开始创作的东西...

题:


我这样做正确吗?感觉很冗长,但这也许是路要走。
如何完成?我缺少例如foo.length ...


PS:Felix,如果您正在阅读本文,请指出我在哪里可以发送请求请求以改进文档!在尝试学习此API时,我很乐意为您提供帮助。哦,还有费利克斯(Felix),你们制作的工具真不错!

最佳答案

直接创建AST节点确实很冗长。但是,jscodeshift会导出一些帮助程序“方法”,这些方法使您可以从字符串生成AST节点,并可以对现有的AST节点进行插值(标记模板为ftw!)。

您上面的示例可以简化为:

  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();


DEMO

请注意,尽管这些模板方法(expressionstatementstatements)有其局限性(只能在可以放置标识符的位置插入AST节点)。



如果要手动创建foo.length,则必须创建MemberExpression

javascript - 从ForInStatement到ForStatement的codemod-LMLPHP

j.memberExpression(
  prop,
  j.identifier('length')
);

关于javascript - 从ForInStatement到ForStatement的codemod,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37577945/

10-11 23:30