Разрешить универсальный тип в проверке кода плагина IntelliJ

Я пишу подключаемый модуль 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. Что мне нужно изменить, чтобы получить ожидаемые типы?

Небольшая справочная информация: я хочу проверить, содержат ли типы, используемые отражением, поле или метод.


person Flat Eric    schedule 02.10.2020    source источник


Ответы (1)


Вы можете получить тип list.get(0) (например, refExpr.getType()), он вернет D PsiTpe.

person Olga Klisho    schedule 06.10.2020
comment
Спасибо за ваш ответ, но это работает только в одном из двух случаев. Он дает D, как и ожидалось, в классе Derived, но T вместо B в Base. Другими словами, когда это определенный класс, мне нужен класс. Когда он ограничен, ему нужно ограничение. - person Flat Eric; 07.10.2020