Разрешить общий тип в проверке кода плагина IntelliJ

#java #intellij-idea #intellij-plugin #intellij-inspections

#java #intellij-идея #intellij-плагин #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 , доступ к которому осуществляется из class 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();
        }
    }
}
  

Я хочу получить наименьший требуемый тип общего типа в контексте использования (the PsiReferenceExpression ). Или относительно моего примера выше:

  • При доступе к list классу in Base я хочу ввести B
  • При доступе к list классу in Derived я хочу ввести D

Но я всегда получаю PsiType:B переменную refTypes . Что мне нужно изменить, чтобы получить ожидаемые типы?

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

Ответ №1:

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

Комментарии:

1. Спасибо за ваш ответ, но это работает только в одном из 2 случаев. Он выдает D , как и ожидалось, в классе Derived , но T вместо B in Base . Другими словами, когда это определенный класс, мне нужен класс. Когда он ограничен, ему нужно ограничение.