6

I have this code base which is rather big ( +/- 500k lines). I'm looking in it to find all the method calls that use a single parameter and that parameter is a specific type.

This means, I want to be able to find method calls like the following:

public class Foo { }
public class Bar { }

public class Doer{
  public void doSomethingFoo(Foo foo) {  }
  public void doSomethingObject(Object object) {  }
}

public class Usage {
  Doer doer = new Doer();
  public doSomething() {
    Foo anObject = new Foo();
    Bar bar = new Bar();

    doer.doSomethingFoo(anObject);
    doer.doSomethingObject(anObject);

    doer.doSomethingObject(bar);
  }
}

Since both doer.doSomethingFoo(anObject) and doer.doSomethingObject(anObject) are called, both those statements should be returned by the search. Similarly, doer.doSomethingObject(bar) is not returned. Of course, I don't know that doer exists.

I'm trying to use the Structural Search of IntelliJ to do so. I've used the following template $Instance$.$Method$($Parameter$), with the following parameters:

$Instance$  -> Text/regexp   = .*
$Method$    -> Text/regexp   = .*
$Parameter$ -> Text/regexp   = Foo
               Minimum count = 1     // Minimum one Foo parameter
               Maximum count = 1     // Maximum one Foo parameter

This returns everything that has a parameter named foo (case-insensitive, apparently). So I'm probably doing something wrong here. But what? How can I get all calls to any method where the only param is of type Foo?

Bas Leijdekkers
  • 23,709
  • 4
  • 70
  • 68
Olivier Grégoire
  • 33,839
  • 23
  • 96
  • 137
  • linked https://stackoverflow.com/questions/37837061/matching-chained-method-calls-with-structural-search – TT-- Aug 17 '18 at 14:40
  • linked https://stackoverflow.com/questions/17861540/how-can-you-use-structural-search-to-find-constructor-calls-for-subclasses-of-a – TT-- Aug 17 '18 at 14:40
  • linked https://stackoverflow.com/questions/15088703/how-can-i-use-intellij-structural-search-to-find-all-methods-that-use-two-named – TT-- Aug 17 '18 at 14:41
  • possibly relevant, https://stackoverflow.com/questions/45882590/structural-search-to-match-method-call-with-generic-parameter – TT-- Aug 17 '18 at 14:58

1 Answers1

2

You are almost there. All you need to do now is set the Expression type (regexp) of $Parameter$ to Foo and leave Text/regexp blank. Additionally you may want to enable the Apply constraint within type hierarchy checkbox, to find subclasses of Foo too.

Note that you can leave the Text/regexp of all variables blank. This is equivalent to .*.

Bas Leijdekkers
  • 23,709
  • 4
  • 70
  • 68
  • This is just great! However, I don't think I could really have found it myself: the texts don't really seem explicit about what those options do. – Olivier Grégoire Jun 24 '16 at 08:02
  • Which texts did you look at? Perhaps we can get them improved? – Bas Leijdekkers Jun 24 '16 at 08:19
  • 1
    Well, for one "text/regexp for java expression type". "java expression type" is totally unclear, I dismissed it on that basis only. (I'm not a native English speaker, to be complete). I actually tested "text/regexp for formal argument type of the method", which seemed more like what I wanted, but I couldn't get the `doer.doSomethingObject(foo)` call, for instance. For the "java expression type", I'd use something like "java argument class or interface". I know what a "type" is, but I don't expect to read it here, especially when `Ctrl+N` says "Enter class name" and returns interfaces as well. – Olivier Grégoire Jun 24 '16 at 08:26
  • Which version of IntelliJ IDEA are you using? – Bas Leijdekkers Jun 24 '16 at 08:32
  • There are indeed some improvements that could be made in this area. However to try and clarify things: whenever the $variable$ is used as an expression (it has a value, e.g. 1+1 or a method call), you can use `Expression type` to match on the type of that expression. So this could also be `boolean` for example. For some usage examples look at the boxing/unboxing Existing Templates. – Bas Leijdekkers Jun 24 '16 at 08:35
  • Currently I'm using version 12.1.8. My company should offer me an upgrade soon, but we're not there yet. – Olivier Grégoire Jun 24 '16 at 08:36
  • 1
    OK, in that case improvements to Structural Search have been made in the newer IntelliJ IDEA versions and more are coming. – Bas Leijdekkers Jun 24 '16 at 08:42
  • What is difference between what @OlivierGrégoire tried, (`$Parameter$ -> Text/regexp = Foo`) and setting the `Expression type (regexp)` of $Parameter$ to `Foo` ? Would they not match the same things? – TT-- Aug 17 '18 at 14:33
  • 1
    Text/regexp matches the literal text of the expression, so would match `anObject` in the original posters example. Expression type matches the type of the expression (`Foo` in the example). – Bas Leijdekkers Aug 19 '18 at 11:24