我经常需要在重构代码时重命名变量,我目前使用正则表达式以一种有点hacky的方式进行 - 我最终不得不为缺乏实际结构而提供愚蠢的文本解决方法,例如,将'req'重命名为'请求'并避免使用类似名称的副作用,例如'require'。
考虑这个问题:它有点像用正则表达式修改DOM:它只是不起作用。
我已经了解了AST和代码结构修改工具,如Esprima。 是否有重命名变量的工具,基于Esprima或其他?
答案 0 :(得分:3)
看起来http://graspjs.com/就是这样做的。
grasp selector --replace replacement file.js
例如,要将'el'重命名为'element':
grasp '#el' --replace 'element' index.js
Visual Studio Code还包含一个真正的替代工具。只需右键单击一个标记,然后选择重命名符号。
答案 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。)