Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Scope.prototype.rename(oldName, newName) #133

Open
benjamn opened this issue Nov 4, 2015 · 4 comments
Open

Implement Scope.prototype.rename(oldName, newName) #133

benjamn opened this issue Nov 4, 2015 · 4 comments

Comments

@benjamn
Copy link
Owner

benjamn commented Nov 4, 2015

@OliverJAsh asked on https://gitter.im/benjamn/recast if it was possible to determine what declaration(s) were responsible for a given variable reference.

Here's the code I came up with at first:

types.visit(ast, {
  visitIdentifier(path) {
    var node = path.node;
    if (node.name === "x") {
      var xScope = path.scope.lookup("x");
      if (xScope) {
        // Iterate over all the Identifiers used to declare x and rename them to y.
        // TODO Might need to be careful not to do this more than once?
        xScope.getBindings().x.forEach(function (idPath) {
          idPath.node.name = "y";
        });
        node.name = "y"; // Rename the identifier too!
      }
    }
    this.traverse(path);
  }
});

As I was writing it out, I realized the common case (renaming) could be accomplished with a much nicer API:

types.visit(ast, {
  visitIdentifier(path) {
    var node = path.node;
    if (node.name === "x") {
      var xScope = path.scope.lookup("x");
      if (xScope) {
        xScope.rename("x", "y");
      }
    }
    this.traverse(path);
  }
});

Open question: what should Scope.prototype.rename return? Perhaps a list of paths to references, since scanning for references in nested scopes is potentially expensive?

@fkling
Copy link
Contributor

fkling commented Nov 4, 2015

FWIW, this is the implementation I use in jscodeshift: https://github.com/facebook/jscodeshift/blob/v0.3.8/src/collections/VariableDeclarator.js#L74-L102

@OliverJAsh
Copy link

Just for clarity, this is the problem I'm trying to solve. I have an object, foo, which has renamed its method from a to b. I want to update all my usages:

var x = foo.a;

/*
Result:
var x = foo.b;
*/

I search for member expressions whereby the object matches foo and update the property (from a to b). However, foo may also be referenced elsewhere, in which case I need to update the properties for those usages, too. That's the part I'm struggling to do:

var ref = foo;
ref.a;

/*
Desired result:
var ref = foo;
ref.b;
*/

@zhangdaren
Copy link

This year is 2021, Not support scope rename?

@zhangdaren
Copy link

pr has been submitted.

#607

Add rename function into scope, like Babel function path.scope.rename(oldName, newName)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants