IntelliJ структурный поиск находит производные классы, если базовый класс соответствует критериям - PullRequest
0 голосов
/ 13 ноября 2018

Предположим, у меня есть базовый класс с полем refCount. Я случайно создаю производный класс, который также объявляет поле с тем же именем. (На самом деле, имя не важно: важен тип, а именно ReferenceCount; но имена довольно последовательны.) Это пустая трата памяти, поэтому было бы неплохо иметь возможность автоматически находить такие вещи. Можно ли это сделать с помощью структурного поиска (или каким-либо другим способом)?

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

Похоже, что новая версия IntelliJ (2018.3) сделала это довольно легко, хотя и немного неловко. Если бы я знал, что это произойдет, у меня был бы соблазн использовать предварительный выпуск.

Хитрость заключается в том, чтобы сначала создать (и сохранить!) Шаблон поиска для базового класса; например, вот так:

class $Class$ {RefCount $count$;}

и затем сделайте что-то вроде этого:

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

А затем добавьте «ссылочный» фильтр для $Base$, который ссылается на сохраненный вами шаблон.

Этот прием не работает, если Child расширяет Parent, который, в свою очередь, расширяет GrandParent, где поле объявляется в Child и в GrandParent, но не в Parent. Я думаю, что это можно исправить, чтобы работать в этом случае без особых проблем, но на самом деле я не знаю, как это сделать.

0 голосов
/ 16 ноября 2018

Похоже, что проверка Java | Visibility | Field name hides field in superclass делает нечто похожее на то, что вам нужно.

Если вы хотите сделать это с помощью Структурного поиска, вы можете сделать что-то вроде этого. Шаблон поиска:

class $X$ {
  RefCount $f$;
}

И добавьте следующий фильтр «script» в поле «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;
...