Work with structural search and replace
The structural search and replace is a powerful tool that can search for a specific pattern of code and add filters that can narrow your search.
In this tutorial we will search for field declarations, add filters, and create a code inspection based on the modified template. If you want, you can watch the related video before we dive in. The video might slightly differ since it was done for the earlier version of IntelliJ IDEA.
Let's open the Search Structurally dialog and use one of the existing templates for our search.
Use an existing template (field declaration)
From the main menu, select
.In the Structural Search dialog, click and select Existing Templates.
In the Existing Templates dialog, under the node, select all fields of a class which will look for all field declarations and click OK.
Click Find to run our search.
As a result, in the Find tool window, IntelliJ IDEA shows all the fields declared in our Java code.
Now, let's return to our structural search dialog to alter the predefined template a bit. By the way, we can use the Search Everywhere window to access the search dialog.
Alter the predefined template
Press Shift twice to open the Search Everywhere window.
Start typing the search query, click Search Structurally in the list of the search results to open our structural search dialog.
In the Structural Search dialog, let's update our template to search only for the final fields, by adding
final
before the$Field$
variable. Notice that the code completion is supported in the dialog.We'll search for our code recursively, match the case, and search only in Java type files.
When we change the scope, IntelliJ IDEA can notify you right away whether or not the code pattern can be found in the specified scope.
Check the result in the Find tool window.
With the structural search, we can conduct some interesting searches. Let's choose another existing template (method calls) as our example.
Use an existing template (method calls)
In the Structural Search dialog, click and select Existing Templates.
Open the list of the existing templates, and select the method calls template under the Expressions node.
If we run the search now, we'll end up with results that include all the method call in our code. So, we should alter our template a bit and use filters to be more specific of what we are looking for. Let's add a filter
Text
and define a method calledprint
. We'll look for calls to a method calledprint
.We can add a regex expression, for example, find all the calls to methods that contain
print
. To do that let's switchprint
toprint.*
.Now the result of our search will include not only print, but also
println
andprintf
.Let's change our search pattern so that the result will only display methods that take only a single parameter. Click the
$Parameter$
variable and add the count filtermin=1
max=1
.In this case, we'll have fewer search results.
Let's assume we're doing this search to replace all these method calls with logging calls instead of System.out
. The logging methods take only strings and no other types.
First, let's find methods that pass the string.
In the Structural Search dialog, add a filter Type for the
$Parameter$
variable.Click Search. As a result, we see a list of print methods that take only literal string or a variable of type
String
.
Now let's do our replacement.
Replace code
Use the Search Everywhere window to access Structural Replace.
In the Structural Replace dialog in the Replace Template add code with which you want to replace our search results. In our case it is
java.util.logging.Logger.getLogger(this.getClass().getName()).fine($Parameter$)
Click Find.
Check the results in the Find tool window and use the replace options to replace all of the results or just the selected ones.
As you can see the code was changed.
We can save this template to refer to it later if we need.
Save the modified template
In the Structural Replace dialog, click .
In the list that opens, select Save Template.
Let's add the name of our template (print String calls) and click OK.
The template is saved under the User Defined node in the Existing Templates dialog.
While in the Structural Replace dialog, we can click to check out the history of your recent searches and quickly rerun any of them.
We can also use our template as an inspection, so when we come across the same code, we'll see a warning and can quickly replace the code.
Create a custom inspection
In the Find tool window, when you get the results for the replace pattern, click Create Inspection from Template.
In the dialog that opens, let's add the name for our template
print String calls
.If you want you can add a tooltip and click OK.
In the Settings/Preferences dialog (Ctrl+Alt+S), go to .
On the Inspections page, open the Structural search node to locate the created inspection.
Now we can quickly fix the code in the editor or use the Problems view where we can check a warning with the suggestion to replace it with the new code.
We can add a custom structural search inspection right from the inspections settings.
Create a custom inspection from the inspections settings
In the Settings/Preferences dialog (Ctrl+Alt+S), go to .
On the Inspections page, select the Structural search node and click . We can base our inspection either on a search template or a replace template. Let's select Add Replace Template.
In the Structural Replace dialog, let's slightly change our search pattern. Let's change the
Type
filter for our$Parameter$
variable toint
.In the replace pattern let's tweak our code.
java.util.logging.Logger.getLogger(this.getClass().getName()).fine(String.valueOf($Parameter$))
In the dialog that opens let's add a name of our inspection
print int calls
and click OK.The new inspection is added under the Structural search, and we can run it to search for instances that print an integer. When code like this is found, we can replace it with the logger call and convert the found parameter into a string.
We can run our inspection separately using its name.
Run the structural search inspection
From the main menu, select
(Ctrl+Alt+Shift+I).In the dialog that opens, let's enter the name of our inspection
print String calls
.In the Run 'print String calls' dialog, let's leave default options and click OK.
We can review our results in the Inspection results tool window.