IntelliJ structural search find derived classes if base class matches criteria

367 Views Asked by At

Suppose I have a base class with a field refCount. I accidentally create a derived class which ALSO declares a field with the same name. (Actually, the name is not important: what matters is the type, which is ReferenceCount; but the names are pretty consistent.) This is a waste of memory, so it would be nice to be able to find such things automatically. Can this be done with Structural Search (or some other way for that matter)?

2

There are 2 best solutions below

6
On BEST ANSWER

It looks like the Java | Visibility | Field name hides field in superclass inspection does something similar to what you need.

If you want to do this with Structural Search, you could do something like this. Search template:

class $X$ {
  RefCount $f$;
}

And add the following "script" filter on the "complete match":

import com.intellij.psi.*;
for (PsiClass aClass : X.getSupers()) { // X refers to the template var $X$
  for (PsiField field : aClass.getAllFields()) {
    // compares the type of the super field with the type of field $a$
    if (field.getType().equals(a.getType())) {
      return true;
    }
  }
}
return false;
1
On

It looks like the new version of IntelliJ (2018.3) has made this fairly easy, albeit slightly awkward. Had I known this was coming I would have been tempted to use the preview release.

The trick is to first create (and save!) a search template for the base class; for instance like this:

class $Class$ {RefCount $count$;}

and then do something like this:

class $Child$ extends $Base$ {RefCount $count$;}

And then add a "reference" filter for $Base$ which refers to the template you saved.

This trick doesn't work if Child extends Parent which in turn extends GrandParent, where the field is declared in Child and in GrandParent but not in Parent. I think this can be fixed to work for that case without much trouble but I don't actually know how to do it.