JS:为重构重命名变量(使用AST,而不是文本)

时间:2013-10-31 15:24:16

标签: javascript parsing refactoring abstract-syntax-tree

我经常需要在重构代码时重命名变量,我目前使用正则表达式以一种有点hacky的方式进行 - 我最终不得不为缺乏实际结构而提供愚蠢的文本解决方法,例如,将'req'重命名为'请求'并避免使用类似名称的副作用,例如'require'。

考虑这个问题:它有点像用正则表达式修改DOM:它只是不起作用。

我已经了解了AST和代码结构修改工具,如Esprima。 是否有重命名变量的工具,基于Esprima或其他?

3 个答案:

答案 0 :(得分:3)

1。 grasp.js

看起来http://graspjs.com/就是这样做的。

grasp selector --replace replacement file.js

例如,要将'el'重命名为'element':

grasp '#el' --replace 'element' index.js

Official grasp.replace docs.

2。 vscode

Visual Studio Code还包含一个真正的替代工具。只需右键单击一个标记,然后选择重命名符号

enter image description here

答案 1 :(得分:1)

我知道您一直在要求“工具”;但是我认为最好只使用esprima本身以及esprima之上的各种通用工具,然后使用自己的重命名器。因为这真的非常容易,然后您才拥有更多控制权。这是仅12行代码的完整示例。它在github上都使用了escodegen和estraverse,据我所见,它与esprima结合使用的某种“标准”。 esprima本质上提供了解析函数字符串->抽象语法树,而escodegen本质上给出了相反的含义,即抽象语法树->字符串。而estraverse使用遍历方法“走树”,从而有助于对其进行分析或修改。

代码在这里:

function rename(code, renamingObj){
    var ast = esprima.parse(code);
    function callback(node){
        if (node.type==='Identifier') {
            if (node.name in renamingObj){
                node.name = renamingObj[node.name];
            }
        }
    }
    estraverse.traverse(ast, { enter: callback });
    return escodegen.generate(ast);
}

测试用例:

function blah(x,y){
    var difference = x + y;
    var product    = x - y;
    var sum        = x * y;
    return 42;
}
var renamingObj = {
    sum        : 'product',
    difference : 'sum',
    product    : 'difference'
};

运行它:

rename(blah.toString(), renamingObj)

输出:

function blah(x, y) {
    var sum = x + y;
    var difference = x - y;
    var product = x * y;
    return 42;
}

我想说的是,如果您有特殊的事情要做,那么修改上面的代码比浏览一些工具文档要容易得多。

答案 2 :(得分:0)

我们的JavaScript Formatter / Obfuscator可以可靠地执行此操作。它解析JavaScript,构建AST,并打印漂亮版本或丑陋(混淆)版本。 [这些在一起的原因是因为漂亮和丑陋是同一枚硬币的两面!)。

它所做的一件事就是争夺(整个)标识符名称。通过使用AST,它只重命名“整个标识符”;它不会将“req”与“require”混淆,也不会意外修改字符串或评论内容。

您可以告诉它构建所有标识符名称的映射,然后将它们全部重命名为自己;更改只是一个,您将获得重命名效果。标识符映射如下所示:

    x ->  y
    p -> q
    ...

指示将x重命名为y,将p重命名为q等。您需要:

    x -> x
    p -> q
    ...

将p改为q。它很容易生成身份地图 作为你的起点。

我不会说这很方便,但确实有效。它显然没有 了解范围。 (一天!)。

有关详细信息,请参阅我的简历。许多SO主持人讨厌工具问题,当我提供包含工具链接的工具答案时,他们似乎特别不喜欢它。所以你必须自己追踪链接,抱歉。 (如果你认为这是愚蠢的话,请投诉Meta。)