views:

113

answers:

5

Hi,

I need to programmatically rename identifiers within a given scope, for example, a method in java program. For example, given the following java function:

public void doSomething(){
   int x = 10;
   int y = x * 2;
   int z = x + y;
}

after renaming the variables (x to a, y to b, and z to c) I should obtain the following function:

public void doSomething(){
   int a = 10;
   int b = a * 2;
   int c = a + b;
}

How can I programmatically implement such renaming of identifiers and their references?

I have been looking into Eclipse AST and Java Model. In either case I have to implement search for all occurrences of any given identifier, and then replace them. I am wondering if there is a better way to do this (how the Eclipse Refactoring UI supports such variable renaming)? Or, should I look into the Language Toolkit (org.eclipse.ltk.core.refactoring)? Any tutorial, sample code, or suggestion?

Please help.

A: 

Can you just use the default Refactor -> Rename functionality?

Alt-Shift-R

vicjugador
He wants to transform the code programmatically.
Mike Daniels
A: 
  • Select variable
  • Click right mouse button
  • Select refactor
  • Select rename
  • rename variable

Eclipse will rename this variable in all place it's used

Xupypr MV
He wants to transform the code programmatically.
Mike Daniels
Yea, I need to transform the code PROGRAMMATICALLY
Fahim
+1  A: 

This link gives an implementation example of code refactoring.

Harsha Hulageri
The article discusses the Eclipse "Java Development Tooling (JDT)" API. It sounds like exactly what the OP is looking for. Thank you!
Thanks for your response. I have seen this. But I need rename refactoring without GUI. Eclipse has such feature. Is there a way to invoke this from my own program/plugin without GUI-intercation with user?
Fahim
A: 

I really question the wisdom of doing this, but it can be done using an annotation processor. You will have to accept that the annotation processor can not modify existing source code but can create new source code that is basically a clone of the original (except for the renames).

  1. Create annotations that define the search and replace.
  2. Annotate your source code. You can create a source file package-info.java and annotate at the package level.
  3. Your processor could use the Compiler Tree API via the Trees.instance method.
  4. You could extend SimpleTreeVisitor to do the actual copying. It will be tedious, but not very complicated.

The only use case that I can think of for this is that you have prepared source code with variable names that make sense in human language A (e.g. Japanese) and you wish to discuss it with an audience (boss, students, clients, etc.) who are more comfortable with human language B (e.g. Arabic)

Other than that, I can not think of any good reason to go to so much trouble. In the example given, x, y, and z are are local variables. Since there scope is so small, there is really no pressing need to rename.

emory
Thanks a lot for your reply. If I have understood your suggestion, you advised to annotate the source code. Unfortunately I must not edit the source code using Editor UI, so annotating the source code is not permitted for my use case.
Fahim
+1  A: 

I'm unclear as whether you wish to perform this renaming across the board (i.e. all methods in all classes) or just to specific classes which you would identify manually. Assuming the latter, I would recommend that you:

  1. Use the Java reflection API java.lang.reflect to identify all methods defined within the particular class that requires local variable renaming.
  2. Iterate across all methods. For each method, use the org.eclipse.jdt.core API to descend through the hierarchy of compilation elements, selecting locally scoped variable definitions. Get the name of the variable for the compilation unit.
  3. Generate your new variable name. Something like: Old ==> OldRenamed. Apply whatever renaming heuristic you wish at this point.
  4. Invoke the Eclipse development kit org.eclipse.jdt.ui.refactoring API methods to do the variable renaming within the method. Effectively you would be invoking the Eclipse Rename Variable functionality headlessly by using this API.

That should do the trick.

Jeff Knaus
thanks for your suggestion, I will try it, and let know.
Fahim
I am trying to use the "org.eclipse.jdt.internal.corext.refactoring.rename.RenameLocalVariableProcessor". But, to instantiate the class I need to pass an object that implements "org.eclipse.jdt.core.ILocalVariable" interface. The documentation says, "ILocalVariable are pseudo-elements created as the result of a ICodeAssist.codeSelect(...) operation. They are not part of the Java model and they are not included in the children of an IMethod or an IInitializer." Then how can I obtain an instance of ILocalVariable?
Fahim
Oh, that's so simple. Calling ICompilationUnit.codeSelect(...) does the job.
Fahim