Resolve generic type in IntelliJ plugin codecheck

418 Views Asked by At

I write an IntelliJ Plugin that performs some checks on Java code.
For one of these checks I need to know the type of a generic field.

Example:

// 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();
    }
}

The class Base contains a list with a generic parameter T which is accessed from class Base and its derived class Derived.

I have an annotator (might be changed to LocalInspection) that checks the access to list in both classes. This is what I have so far (I left out type- and null-checks for simplicity):

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();
        }
    }
}

I want to get the lowest required type of the generic in context of the usage (the PsiReferenceExpression). Or regarding my example from above:

  • At the access to list in class Base, I want type B
  • At the access to list in class Derived, I want type D

But I always get PsiType:B in the variable refTypes. What do I have to change to get the expected types?

Small background info: I want to check if types, used by reflection, contain the field or method.

1

There are 1 best solutions below

1
On

You may get the type of list.get(0) (i.e like refExpr.getType()), it will return the D PsiTpe.