13

In all my java files of my project, I want to replace occurrences of this:

myObject.getName() == null

With that:

myObject.hasName()

Is there any action or strategy to do this with IntelliJ IDEA?

  • I want it to be specific to the getName method of my class MyClass and not to replace code, that refers to methods called getName of other classes.
  • I want it to find as many matches as possible. It should not care about additional spaces, linebreaks, etc. If the variable has another name (like myObj or objX) it should also work. Calls like getObject().getName() should also be found. (The search has to care about semantics).
  • I want it to be fast and not to require me to go through the hundreds of matches one by one.
Bas Leijdekkers
  • 23,709
  • 4
  • 70
  • 68
slartidan
  • 20,403
  • 15
  • 83
  • 131
  • 1
    Although manually intensive, to reduce the chance of missing the duplicated code comment out `getName()`. You'll then know all of the compilation errors which need to be checked. – Andrew S Apr 18 '17 at 13:08
  • would a simple project-wide search (for `.getName() == null`) and replace (with `.hasName()`) not work? – Woodrow Barlow Apr 18 '17 at 14:15
  • @WoodrowBarlow This is the best answer currently. Still, since `getName` is not very unique, it would replace too many false matches. I'm looking for something that is aware of the context. – slartidan Apr 18 '17 at 14:29

4 Answers4

12

Use Structural Search & Replace (Edit | Find | Replace Structurally...), it is designed for use cases like this.

Use Search template:

$x$.getName() == null

Replacement template:

$x$.hasName()

Click the Edit Variables... button and specify Expression type (regexp) as MyClass. When searching this will also find your example of getObject().getName() == null

Bas Leijdekkers
  • 23,709
  • 4
  • 70
  • 68
6

Use Find and Replace Code Duplicates.

  1. Create the instance method:

    public boolean hasName() {
        return getName() == null;
    }
    
    • To do that, I would suggest selecting myObject.getName() == null, then using actions Refactor | Extract | Method... and Refactor | Move..., so you don't have to type any code.
  2. Click on the method and use Refactor | Find and Replace Code Duplicates.

    • However it will not refactor usages like these:

      String name = myObject.getName();
      if (name == null) {
          ...
      }
      
    • You can also use this action on a non-instance method:

      private boolean hasName(MyClass myObject) {
          return myObject.getName() == null;
      }
      

      which will result in making the method static, then use Refactor | Convert To Instance Method. Same result.

Meo
  • 12,020
  • 7
  • 45
  • 52
2

You can rename getName() to something like putGuidInHereIfYouWantToBeSure() and then do a simple replace in all files with putGuidInHereIfYouWantToBeSure() == null with hasName()

Philipp Hofmann
  • 3,388
  • 26
  • 32
  • I like this, because it is so easy to do and works in many IDEs, not just IntelliJ. However this solution will not find as many variants as the other solutions, because **white spaces**, comments, etc. can hinder the replacement to work. – slartidan Apr 25 '17 at 11:18
  • If hasName() returns a value type boolean, you will get compile errors for the ones you missed. Furthermore if you have a consistent code formatting, this shouldn't be a problem. – Philipp Hofmann Apr 25 '17 at 11:39
-1

From the intelliJ Documentation


Replacing a piece of text in all the files within the specified path

  1. Do one of the following:
    • On the main menu, choose Edit | Find | Replace in Path.
    • Press Ctrl+Shift+R
    • Being in the Find In Path dialog box, press Ctrl+Shift+R to switch to Replace In Path dialog box.
  2. In the Replace In Path dialog, specify the search and replace strings, the search options, and the scope. Type the search and replacement text explicitly, or specify patterns using regular expression, or select a previously used piece of text or a pattern from the recent history drop-down list.
    • If you specify the search and/or replacement text through a regular expression, use the $n format in back references (to refer to a previously found and saved pattern).
    • To use a backslash character \ in a regular expression, escape the meaningful backslash by inserting three extra backslashes in preposition: \\\\.
  3. Click Replace in Find Window. IntelliJ IDEA displays the encountered occurrences of the search string in the Find tool window, selects the first occurrence and opens the file with this occurrence in the editor and moves the focus to it.
    At the same time, IntelliJ IDEA opens the Replace Usage dialog box, with the full path to the encountered occurrence in the title bar: enter image description here Do one of the following:
    • To have the selected occurrence replaced, click Replace.
    • To preserve the selected occurrence and move to the next one, click Skip.
    • To have all the occurrences of the search string in the currently active tab replaced, click Replace All in This File.
    • To preserve the occurrences of the search string in the currently active tab (any) and move to the next file, click Skip to Next File.
    • To have all the detected occurrences replaced, click All Files.
    • To switch to the manual mode, click Preview. The Replace Usage dialog box closes and the focus moves to the Find tool window. Do one of the following:
      • Browse through the list of detected occurrences, select the ones you want to replace and then click Replace Selected.
      • To have all the occurrences changed click Replace All.
Woodrow Barlow
  • 8,477
  • 3
  • 48
  • 86
jehutyy
  • 364
  • 3
  • 11
  • thank you for editing I didn't know it was possible to include a whole page. – jehutyy Apr 18 '17 at 14:24
  • i just did it by hand. it is a pain in the neck, but it's important for posterity's sake -- in case the server hosting the information becomes unavailable. you can improve this question further by giving an example that uses this technique to answer the OP's specific use-case. – Woodrow Barlow Apr 18 '17 at 14:42