Bulk refactor rename using structural search and replace
Answered
This topic has been started a few times in the past put with no resolution as far as I can see. (https://intellij-support.jetbrains.com/hc/en-us/community/posts/206239639-mass-rename for example)
I basically want to find all fields with a prefix in my code base, and refactor rename to remove the prefix
mField1 -> field1
mField2 -> field2
etc
I can find them all, but I am stuck coming up with a script to do the rename.
Is this possible? I have read that the structural replace has access to the entire IntelliJ API and the possibilities are limitless. So I hoping a simple rename based on a simple string transform should be doable?
Please help, my alternative is regex replace and it will cause issues...
Please sign in to leave a comment.
Hi Martinen,
Please make sure to update to version 2019.3 to benefit from latest updates to Structural Replace functionality.
Let's say your search template script looks like this:
$FieldType$ $Field$ = $Init$;\b^[a-z][A-Z].*\btext=\b^[a-z][A-Z].*\b$Field2$and assign the following script to it:script=Field.name.substring(1).uncapitalize()Alternatively, you can import the following template to the Structural Replace dialog from clipboard:
If you save the template, you can use it to do the batch rename via the structural search inspection (Analyze > Inspect Code > Inspection Profile > Structural search inspection). Enable the inspection, add a replace template in the Options area and click OK to run it. Inspection hits will be under 'General' entry. 'Replace Structurally' button will do the renaming for all the found issues.
If you wish for the SSR functionality to cover more complicated bulk rename cases, you can vote for https://youtrack.jetbrains.com/issue/IDEA-12246 and add yourself to watchers to stay updated on the progress.
I did try this out, but only the initialising line was affected
so in the constructor mField1 changed to field1 (great!)
but elsewhere in the file I had lines like:
String value = mField1; Which doesn't compile as mField1 no longer exists.
Would it be possible to do a more general search for all references to fields and change the name? Would "this." be added in cases like:
class myClass {
String mField1;
public myClass(String field1) {
mField1 = field1; <-- this. is needed when this line becomes field1 = field1
}
...
}
I read somewhere that IntelliJs refactoring API would be available in the sctipr for the new field. So instead of a string mutation, could a refactor rename be used?
Thanks for the help so far!
Hi Martinen,
Per-field renaming can be done via the Refactor Rename dialog.
Position your cursor on the variable name and invoke the dialog with
Shift+F6+F6.Enter the replacement name.
Optionally enable/disable search in comments and strings or limit search scope.
> this. is needed when this line becomes field1 = field1
It will be added automatically. Post refactoring, you can inspect your code for all such cases and convert them using the Instance field access not qualified with 'this' inspection. It can be found under File > Settings > Editor > Inspections > Java > Code style issues.
Hi,
I am looking for a bulk refactor operation as there are 100 of thousands of fields which need renaming.
all the fields so match the pattern m[A-Z][a-zA-Z]* though so they are easy to identify.
Hi Martinen,
To achieve your goal, you can use the structural search template from my initial reply and add another one that is going to replace the mField1's in assignment occurrences like
String value = mField1;.You can then run the Replace in Path dialog (
Ctrl+Shift+R) and search for this regex:\bm[A-Z]\w*\b- it will get you the remaining occurrences of mField1's across the project if any.Complex refactor renaming is not possible via the dialog I mentioned earlier (
Shift+F6) because it doesn't give you the ability to use scripted logic to replace values smartly - only per-symbol replacement.