最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - JS: rename variables for refactor (using an AST, not text) - Stack Overflow

programmeradmin3浏览0评论

I often need to rename variables when refactoring code, which I currently do in a somewhat hacky way using regexs - I end up having to e with silly text workaround workarounds for the lack of actual structure, eg, rename 'req' to 'request' and avoid side effects with similar names like 'require'.

Thinking about this stuff: it's kind of like modifying the DOM with regexs: it just doesn't work.

I've learnt about ASTs and code structure modification tools like Esprima. Is there a tool to rename variables, Esprima based or otherwise?

I often need to rename variables when refactoring code, which I currently do in a somewhat hacky way using regexs - I end up having to e with silly text workaround workarounds for the lack of actual structure, eg, rename 'req' to 'request' and avoid side effects with similar names like 'require'.

Thinking about this stuff: it's kind of like modifying the DOM with regexs: it just doesn't work.

I've learnt about ASTs and code structure modification tools like Esprima. Is there a tool to rename variables, Esprima based or otherwise?

Share Improve this question asked Oct 31, 2013 at 15:24 mikemaccanamikemaccana 124k110 gold badges432 silver badges534 bronze badges 5
  • Huh? What IDE are you using? Most allow you to rename variables just fine. shift+F6 in PHPStorm (and probably most other IDEs) – Halcyon Commented Oct 31, 2013 at 15:25
  • @FritsvanCampen Using Sublime... by it default it emphasis 'use ⌘D to rename variables' which is just text based. – mikemaccana Commented Oct 31, 2013 at 15:28
  • 1 A non-programmer colleague of mine uses that one. I don't think it does any kind of code analysis. You need an IDE that understands your target programming language of course. – Halcyon Commented Oct 31, 2013 at 15:30
  • @FritsvanCampen Yep, either an IDE with an AST based tool built in or a separate mand line AST tool would do nicely. – mikemaccana Commented Oct 31, 2013 at 15:30
  • Related: stackoverflow./questions/17212639/… – flup Commented Nov 15, 2013 at 23:41
Add a ment  | 

3 Answers 3

Reset to default 4

1. grasp.js

It looks like http://graspjs./ does exactly this.

grasp selector --replace replacement file.js

For example, to rename 'el' to 'element':

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

Official grasp.replace docs.

2. vscode

Visual Studio Code also includes a real replacement tool. Just right click a token and choose rename symbol.

I know you've been asking for 'a tool'; but I think it's better to use just esprima itself and the various general purpose tools on top of esprima, and roll your own renamer. Because it's really really easy, and then you have more control. Here is a plete example in just 12 lines of code. It uses escodegen and estraverse, both on github, and, as far as I can see kind of 'the standard' to use in conjunction with esprima. While esprima essentially gives the parse function string -> abstract syntax tree, escodegen essentially gives the reverse of that, i.e. abstract syntax tree -> string. And estraverse 'walks the tree' with the traverse method, thus helping to analyze or modify it.

Here the code:

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

Testcase:

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'
};

run it:

rename(blah.toString(), renamingObj)

output:

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

I would say, if you have something special to do, it's easier to modify above code than sifting through some tool documentation.

Our JavaScript Formatter/Obfuscator will do this reliably. It parses JavaScript, builds an AST, and either prints a pretty version, or an ugly (obfuscated) version. [The reason these are together is because pretty and ugly are opposite sides of the same coin!).

One of the things it does is scramble (whole) identifier names. By using the AST, it only renames "whole identifiers"; it won't confuse "req" with "require", or modify string or ment content by accident.

You can tell it to build a map of all identifier names, and then rename them all to themselves; change just one, and you get your rename effect. The identifier map looks like this:

    x ->  y
    p -> q
    ...

directing that x gets renamed to y, p to q, etc. You want:

    x -> x
    p -> q
    ...

to change just p to q. Its pretty easy to produce the identity map as your starting place.

I wouldn't say this is convenient, but it does work. It obviously doesn't know anything about scopes. (someday!).

See my bio for details. Many SO moderators hate tool questions, and they especially seem to dislike it when I provide a tool answer that includes a link to the tool. So you'll have to track down the link yourself, sorry. (Complain on Meta if you think this is dumb).

发布评论

评论列表(0)

  1. 暂无评论