Я пишу подключаемый модуль IntelliJ, который выполняет некоторые проверки кода Java.
Для одной из этих проверок мне нужно знать тип универсального поля.
Пример:
// Model classes B and D
public class B {
void doB() {
}
}
public class D extends B {
void doD() {
}
}
// Classes that use the model classes
public class Base<T extends B> {
protected List<T> list;
private void test() {
list.get(0).doB();
}
}
public class Derived extends Base<D> {
private void test() {
list.get(0).doD();
}
}
Класс Base
содержит список с общим параметром T
, доступ к которому осуществляется из класса Base
и его производного класса Derived
.
У меня есть аннотатор (может быть изменен на LocalInspection), который проверяет доступ к list
в обоих классах. Это то, что у меня есть до сих пор (для простоты я не учел проверки типов и нулей):
public class GenAnno implements Annotator {
@Override
public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
if (element instanceof PsiReferenceExpression) {
PsiReferenceExpression refExpr = (PsiReferenceExpression)element;
PsiElement target = refExpr.resolve();
PsiField field = (PsiField) target;
PsiClassType fieldType = (PsiClassType) field.getType();
PsiClassType itTyp = (PsiClassType) PsiUtil.extractIterableTypeParameter(fieldType, false);
PsiClass cl = itTyp.resolve();
PsiTypeParameter tpara = (PsiTypeParameter) cl;
JvmReferenceType[] refTypes = tpara.getBounds();
}
}
}
Я хочу получить самый низкий требуемый тип универсального в контексте использования (PsiReferenceExpression
). Или относительно моего примера сверху:
- При доступе к
list
в классеBase
я хочу типB
- При доступе к
list
в классеDerived
я хочу типD
Но я всегда получаю PsiType:B
в переменной refTypes
. Что мне нужно изменить, чтобы получить ожидаемые типы?
Небольшая справочная информация: я хочу проверить, содержат ли типы, используемые отражением, поле или метод.